<commit_before>/*
	This file is part of the Rendering library.
	Copyright (C) 2014 <NAME> <<EMAIL>>

	This library is subject to the terms of the Mozilla Public License, v. 2.0.
	You should have received a copy of the MPL along with this library; see the
	file LICENSE. If not, you can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifdef RENDERING_HAS_LIB_OPENCL
#include "Program.h"

#include "Context.h"
#include "Device.h"
#include "CLUtils.h"

COMPILER_WARN_PUSH
COMPILER_WARN_OFF(-Wpedantic)
COMPILER_WARN_OFF(-Wold-style-cast)
COMPILER_WARN_OFF(-Wcast-qual)
COMPILER_WARN_OFF(-Wshadow)
COMPILER_WARN_OFF(-Wstack-protector)
#include <CL/cl.hpp>
COMPILER_WARN_POP

#include <Util/Macros.h>
#include <Util/IO/FileUtils.h>

#include <iostream>

namespace Rendering {
namespace CL {

Program::Program(Context* _context) : Util::ReferenceCounter<Program>(), context(_context) {
	//cl_int err;
	//program.reset(new cl::Program(*context->_internal(), "", &err));
	//THROW_ERROR_IF(err != CL_SUCCESS, getErrorString(err));
}

Program::Program(Context* _context, const std::vector<std::string>& _sources) : Util::ReferenceCounter<Program>(), context(_context) {
	cl_int err;
	cl::Program::Sources cl_sources;
	for(auto src : _sources)
		cl_sources.push_back(std::make_pair(src.c_str(),src.size()));
	program.reset(new cl::Program(*context->_internal(), cl_sources, &err));
	THROW_ERROR_IF(err != CL_SUCCESS, getErrorString(err));
}

Program::~Program() = default;

Program::Program(const Program& _program) : Util::ReferenceCounter<Program>(), program(new cl::Program(*_program.program.get())), context(_program.context) { }

//Program::Program(Program&& program) = default;

//Program& Program::operator=(Program&&) = default;

bool Program::build(const std::vector<DeviceRef>& devices, const std::string& options_ /*= ""*/) {
	THROW_ERROR_IF(!program, "Program has no source!");
	std::vector<cl::Device> cl_devices;
	for(auto device : devices)
		cl_devices.push_back(*device->_internal());

	std::string opt = options_;
	for(auto o : options)
		opt += o;
	cl_int err = program->build(cl_devices, opt.c_str());
	if(err != CL_SUCCESS) {
		WARN("Failed to build program (" + getErrorString(err) + ")");
		for(auto device : devices) {
			std::cerr << "Device: \t" << device->getName() << std::endl;
			std::cerr << "Build Status: " << static_cast<uint32_t>(getBuildStatus(device.get())) << std::endl;
			std::cerr << "Build Options:\t" << getBuildOptions(device.get()) << std::endl;
			std::cerr << "Build Log:\t " << getBuildLog(device.get()) << std::endl;
		}
	}
	return err == CL_SUCCESS;
}

BuildStatus_t Program::getBuildStatus(Device* device) const {
	cl_int status = program->getBuildInfo<CL_PROGRAM_BUILD_STATUS>(*device->_internal());
	switch (status) {
		case CL_BUILD_SUCCESS:
			return BuildStatus_t::Success;
		case CL_BUILD_IN_PROGRESS:
			return BuildStatus_t::InProgress;
		case CL_BUILD_ERROR:
			return BuildStatus_t::Error;
		default:
			return BuildStatus_t::None;
	}
}

std::string Program::getBuildOptions(Device* device) const {
	return program->getBuildInfo<CL_PROGRAM_BUILD_OPTIONS>(*device->_internal());
}

std::string Program::getBuildLog(Device* device) const {
	return program->getBuildInfo<CL_PROGRAM_BUILD_LOG>(*device->_internal());
}

std::vector<char*> Program::getBinaries() const {
	return program->getInfo<CL_PROGRAM_BINARIES>();
}

std::vector<size_t> Program::getBinarySizes() const {
	return program->getInfo<CL_PROGRAM_BINARY_SIZES>();
}

std::vector<DeviceRef> Program::getDevices() const {
	std::vector<DeviceRef> out;
	std::vector<cl::Device> cl_devices = program->getInfo<CL_PROGRAM_DEVICES>();
	for(auto dev : cl_devices)
		out.push_back(new Device(context->getPlatform(), &dev));
	return out;
}

uint32_t Program::getNumDevices() const {
	return program->getInfo<CL_PROGRAM_NUM_DEVICES>();
}

std::string Program::getKernelNames() const {
	return program->getInfo<CL_PROGRAM_KERNEL_NAMES>();
}

uint32_t Program::getNumKernels() const {
	return program->getInfo<CL_PROGRAM_NUM_KERNELS>();
}

std::string Program::getSource() const {
	return program->getInfo<CL_PROGRAM_SOURCE>();
}


void Program::attachSource(const std::string& source) {
	sources.push_back(source);

	cl_int err;
	cl::Program::Sources cl_sources;
	for(auto src : sources)
		cl_sources.push_back(std::make_pair(src.c_str(),src.size()));
	program.reset(new cl::Program(*context->_internal(), cl_sources, &err));
	THROW_ERROR_IF(err != CL_SUCCESS, getErrorString(err));
}

void Program::attachSource(const Util::FileName& file) {
	attachSource(Util::FileUtils::getFileContents(file));
}

void Program::addDefine(const std::string& key, const std::string& value) {
	options.push_back(" -D" + key + (value.empty() ? "" : ("=" + value)));
}

void Program::addInclude(const std::string& dir) {
	options.push_back(" -I " + dir);
}

void Program::addInclude(const Util::FileName& dir) {
	addInclude(dir.getDir());
}


} /* namespace CL */
} /* namespace Rendering */
#endif /* RENDERING_HAS_LIB_OPENCL */<commit_msg>bugfix: OpenCL: added quotation marks to include paths<commit_after>/*
	This file is part of the Rendering library.
	Copyright (C) 2014 <NAME> <<EMAIL>>

	This library is subject to the terms of the Mozilla Public License, v. 2.0.
	You should have received a copy of the MPL along with this library; see the
	file LICENSE. If not, you can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifdef RENDERING_HAS_LIB_OPENCL
#include "Program.h"

#include "Context.h"
#include "Device.h"
#include "CLUtils.h"

COMPILER_WARN_PUSH
COMPILER_WARN_OFF(-Wpedantic)
COMPILER_WARN_OFF(-Wold-style-cast)
COMPILER_WARN_OFF(-Wcast-qual)
COMPILER_WARN_OFF(-Wshadow)
COMPILER_WARN_OFF(-Wstack-protector)
#include <CL/cl.hpp>
COMPILER_WARN_POP

#include <Util/Macros.h>
#include <Util/IO/FileUtils.h>

#include <iostream>

namespace Rendering {
namespace CL {

Program::Program(Context* _context) : Util::ReferenceCounter<Program>(), context(_context) {
	//cl_int err;
	//program.reset(new cl::Program(*context->_internal(), "", &err));
	//THROW_ERROR_IF(err != CL_SUCCESS, getErrorString(err));
}

Program::Program(Context* _context, const std::vector<std::string>& _sources) : Util::ReferenceCounter<Program>(), context(_context) {
	cl_int err;
	cl::Program::Sources cl_sources;
	for(auto& src : _sources)
		cl_sources.push_back(std::make_pair(src.c_str(),src.size()));
	program.reset(new cl::Program(*context->_internal(), cl_sources, &err));
	THROW_ERROR_IF(err != CL_SUCCESS, getErrorString(err));
}

Program::~Program() = default;

Program::Program(const Program& _program) : Util::ReferenceCounter<Program>(), program(new cl::Program(*_program.program.get())), context(_program.context) { }

//Program::Program(Program&& program) = default;

//Program& Program::operator=(Program&&) = default;

bool Program::build(const std::vector<DeviceRef>& devices, const std::string& options_ /*= ""*/) {
	THROW_ERROR_IF(!program, "Program has no source!");
	std::vector<cl::Device> cl_devices;
	for(auto device : devices)
		cl_devices.push_back(*device->_internal());

	std::string opt = options_;
	for(auto& o : options)
		opt += o;
	cl_int err = program->build(cl_devices, opt.c_str());
	if(err != CL_SUCCESS) {
		WARN("Failed to build program (" + getErrorString(err) + ")");
		for(auto device : devices) {
			std::cerr << "Device: \t" << device->getName() << std::endl;
			std::cerr << "Build Status: " << static_cast<uint32_t>(getBuildStatus(device.get())) << std::endl;
			std::cerr << "Build Options:\t" << getBuildOptions(device.get()) << std::endl;
			std::cerr << "Build Log:\t " << getBuildLog(device.get()) << std::endl;
		}
	}
	return err == CL_SUCCESS;
}

BuildStatus_t Program::getBuildStatus(Device* device) const {
	cl_int status = program->getBuildInfo<CL_PROGRAM_BUILD_STATUS>(*device->_internal());
	switch (status) {
		case CL_BUILD_SUCCESS:
			return BuildStatus_t::Success;
		case CL_BUILD_IN_PROGRESS:
			return BuildStatus_t::InProgress;
		case CL_BUILD_ERROR:
			return BuildStatus_t::Error;
		default:
			return BuildStatus_t::None;
	}
}

std::string Program::getBuildOptions(Device* device) const {
	return program->getBuildInfo<CL_PROGRAM_BUILD_OPTIONS>(*device->_internal());
}

std::string Program::getBuildLog(Device* device) const {
	return program->getBuildInfo<CL_PROGRAM_BUILD_LOG>(*device->_internal());
}

std::vector<char*> Program::getBinaries() const {
	return program->getInfo<CL_PROGRAM_BINARIES>();
}

std::vector<size_t> Program::getBinarySizes() const {
	return program->getInfo<CL_PROGRAM_BINARY_SIZES>();
}

std::vector<DeviceRef> Program::getDevices() const {
	std::vector<DeviceRef> out;
	std::vector<cl::Device> cl_devices = program->getInfo<CL_PROGRAM_DEVICES>();
	for(auto& dev : cl_devices)
		out.push_back(new Device(context->getPlatform(), &dev));
	return out;
}

uint32_t Program::getNumDevices() const {
	return program->getInfo<CL_PROGRAM_NUM_DEVICES>();
}

std::string Program::getKernelNames() const {
	return program->getInfo<CL_PROGRAM_KERNEL_NAMES>();
}

uint32_t Program::getNumKernels() const {
	return program->getInfo<CL_PROGRAM_NUM_KERNELS>();
}

std::string Program::getSource() const {
	return program->getInfo<CL_PROGRAM_SOURCE>();
}


void Program::attachSource(const std::string& source) {
	sources.push_back(source);

	cl_int err;
	cl::Program::Sources cl_sources;
	for(auto& src : sources)
		cl_sources.push_back(std::make_pair(src.c_str(),src.size()));
	program.reset(new cl::Program(*context->_internal(), cl_sources, &err));
	THROW_ERROR_IF(err != CL_SUCCESS, getErrorString(err));
}

void Program::attachSource(const Util::FileName& file) {
	attachSource(Util::FileUtils::getFileContents(file));
}

void Program::addDefine(const std::string& key, const std::string& value) {
	options.push_back(" -D" + key + (value.empty() ? "" : ("=" + value)));
}

void Program::addInclude(const std::string& dir) {
	options.push_back(" -I \"" + dir + "\"");
}

void Program::addInclude(const Util::FileName& dir) {
	addInclude(dir.getDir());
}


} /* namespace CL */
} /* namespace Rendering */
#endif /* RENDERING_HAS_LIB_OPENCL */
{'fraction_non_alphanumeric': 0.1657748711850971, 'fraction_numerical': 0.0027744748315497426, 'mean_word_length': 6.509672619047619, 'pattern_counts': {'":': 0, '<': 109, '<?xml version=': 0, '>': 101, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2827249', 'n_tokens_mistral': 3543, 'n_tokens_neox': 3429, 'n_words': 669}