// Create a program for all devices associated with the context. cl_program createProgramFromBinary(cl_context context, const char *binary_file_name, const cl_device_id *devices, unsigned num_devices) { // Early exit for potentially the most common way to fail: AOCX does not exist. if(!fileExists(binary_file_name)) { printf("AOCX file '%s' does not exist.\n", binary_file_name); checkError(CL_INVALID_PROGRAM, "Failed to load binary file"); } // Load the binary. size_t binary_size; scoped_array<unsigned char> binary(loadBinaryFile(binary_file_name, &binary_size)); if(binary == NULL) { checkError(CL_INVALID_PROGRAM, "Failed to load binary file"); } scoped_array<size_t> binary_lengths(num_devices); scoped_array<unsigned char *> binaries(num_devices); for(unsigned i = 0; i < num_devices; ++i) { binary_lengths[i] = binary_size; binaries[i] = binary; } cl_int status; scoped_array<cl_int> binary_status(num_devices); cl_program program = clCreateProgramWithBinary(context, num_devices, devices, binary_lengths, (const unsigned char **) binaries.get(), binary_status, &status); checkError(status, "Failed to create program with binary"); for(unsigned i = 0; i < num_devices; ++i) { checkError(binary_status[i], "Failed to load binary for device"); } return program; }
bool Program::loadBinary() { // don't load if not explicitly enabled if (util::envVarValue("SKELCL_LOAD_BINARY") != "YES") return false; // if hash is empty no binary is loaded (maybe be more gentle and just return) ASSERT(!_hash.empty()); for (auto& devicePtr : globalDeviceList) { std::ifstream binaryFile(binaryFilename(_hash, devicePtr), std::ios_base::in | std::ios_base::binary | std::ios_base::ate); if (binaryFile.fail()) { _clPrograms.clear(); return false; } // get the size of the file std::ifstream::pos_type size = binaryFile.tellg(); // allocate memory std::unique_ptr<char[]> binary(new char[size]); // set position in file to the beginning binaryFile.seekg(0, std::ios::beg); // read the hole file binaryFile.read(binary.get(), size); // close it binaryFile.close(); // push the binary on the vector cl::Program::Binaries binaries(1, std::make_pair(binary.get(), size)); std::vector<cl::Device> devices{ devicePtr->clDevice() }; _clPrograms.push_back( cl::Program( devicePtr->clContext(), devices, binaries ) ); LOG_DEBUG_INFO("Load binary for device ", devicePtr->id(), " from file ", binaryFilename(_hash, devicePtr)); } ASSERT(_clPrograms.size() == globalDeviceList.size()); return true; }
cl::Program OCLSample::loadBinary(const std::string& filename) { cl_int result; std::ifstream kernelStream(filename.c_str()); std::string binary(std::istreambuf_iterator<char>(kernelStream), (std::istreambuf_iterator<char>())); kernelStream.close(); cl::Program::Binaries binaries(1, std::make_pair(binary.c_str(), binary.size())); std::vector<cl::Device> devices; devices.push_back(device_); cl::Program program(context_, devices, binaries, NULL, &result); assert(result == CL_SUCCESS && "Failed to load program source"); result = program.build(devices); if(result != CL_SUCCESS) { std::cerr << "Source compilation failed.\n"; std::cerr << program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(device_); assert(false && "Unable to continue"); } return program; }
// Computes distance function for the molecule. // The voxels corresponding to surface points are given zero distance void SurfaceShellDensityMap::resample() { //all scene voxels will be assigned the value -background_val_ //(which is positive and larger than 0) //TODO - change here, the value of the inner voxels should note be //should not be ns*2 but the largest of the inner shell IMP_LOG(VERBOSE,"going to binaries\n"); binaries(num_shells_*2); IMP_LOG(VERBOSE,"after binaries\n"); //find the voxeles that are part of the surface, so we'll have //background, surface and interior voxels std::vector<long> curr_shell_voxels; //all of the voxels that are part of the current shell set_surface_shell(&curr_shell_voxels); //all of the voxels that are part of the next shell std::vector<long> next_shell_voxels; //keeps the shell index for each of the data voxels IMP_LOG(VERBOSE,"reseting shell voxels\n"); std::vector<int> shell_voxels; shell_voxels.insert(shell_voxels.end(),get_number_of_voxels(),-1); for(long i=0;i<get_number_of_voxels();i++) { if (data_[i] == IMP_SURFACE_VAL) { shell_voxels[i]=0; } } long n_voxel_ind,voxel_ind; float dist_from_surface; //the value is the distance of the voxel //from the surface std::vector<long> *curr_p = &curr_shell_voxels; std::vector<long> *next_p = &next_shell_voxels; std::vector<long> *tmp_p; long num_voxels = get_number_of_voxels(); IMP_LOG(VERBOSE,"sampling shells\n"); for (int s_ind = 0; s_ind <num_shells_; s_ind++) { // update voxels with current layer distance and insert indexes //for next shell for(std::vector<long>::iterator it = curr_p->begin(); it != curr_p->end();it++) { voxel_ind = *it; for (unsigned int j = 0; j < neighbor_shift_.size(); j++) { n_voxel_ind = voxel_ind + neighbor_shift_[j]; //the index of the neighbor if ((n_voxel_ind>-1)&&(n_voxel_ind<num_voxels)) { dist_from_surface = data_[voxel_ind] + neighbor_dist_[j]; //if the stored distance of the voxel (voxel_ind) from the surface //is larger than the current calculated one, update if (data_[n_voxel_ind] > dist_from_surface) { data_[n_voxel_ind] = dist_from_surface; // set the voxels for the next shell if (shell_voxels[n_voxel_ind] < s_ind + 1) { next_p->push_back(n_voxel_ind); shell_voxels[n_voxel_ind] = s_ind + 1; } } } } } curr_p->clear(); tmp_p = curr_p; curr_p = next_p; next_p = tmp_p; } //zero outside for(long i=0;i<num_voxels;i++) { if (data_[i]<1.) { data_[i]=0.; } } //incase we want to keep the shells and not the indexes // //now update the voxel data to be the shell index // for(long i=0;i<shell_voxels.size();i++) { // data_[i]=shell_voxels[i]; // } }