#ifndef _OPENCL_PROGRAM_H_ #define _OPENCL_PROGRAM_H_ #include "contexte.h" #include #include #include #include const int ENTREE = CL_MEM_READ_ONLY; const int SORTIE = CL_MEM_READ_WRITE; const int ES = CL_MEM_READ_WRITE; const char* oclErrorString(cl_int error) { static const char* errorString[] = { "CL_SUCCESS", "CL_DEVICE_NOT_FOUND", "CL_DEVICE_NOT_AVAILABLE", "CL_COMPILER_NOT_AVAILABLE", "CL_MEM_OBJECT_ALLOCATION_FAILURE", "CL_OUT_OF_RESOURCES", "CL_OUT_OF_HOST_MEMORY", "CL_PROFILING_INFO_NOT_AVAILABLE", "CL_MEM_COPY_OVERLAP", "CL_IMAGE_FORMAT_MISMATCH", "CL_IMAGE_FORMAT_NOT_SUPPORTED", "CL_BUILD_PROGRAM_FAILURE", "CL_MAP_FAILURE", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "CL_INVALID_VALUE", "CL_INVALID_DEVICE_TYPE", "CL_INVALID_PLATFORM", "CL_INVALID_DEVICE", "CL_INVALID_CONTEXT", "CL_INVALID_QUEUE_PROPERTIES", "CL_INVALID_COMMAND_QUEUE", "CL_INVALID_HOST_PTR", "CL_INVALID_MEM_OBJECT", "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR", "CL_INVALID_IMAGE_SIZE", "CL_INVALID_SAMPLER", "CL_INVALID_BINARY", "CL_INVALID_BUILD_OPTIONS", "CL_INVALID_PROGRAM", "CL_INVALID_PROGRAM_EXECUTABLE", "CL_INVALID_KERNEL_NAME", "CL_INVALID_KERNEL_DEFINITION", "CL_INVALID_KERNEL", "CL_INVALID_ARG_INDEX", "CL_INVALID_ARG_VALUE", "CL_INVALID_ARG_SIZE", "CL_INVALID_KERNEL_ARGS", "CL_INVALID_WORK_DIMENSION", "CL_INVALID_WORK_GROUP_SIZE", "CL_INVALID_WORK_ITEM_SIZE", "CL_INVALID_GLOBAL_OFFSET", "CL_INVALID_EVENT_WAIT_LIST", "CL_INVALID_EVENT", "CL_INVALID_OPERATION", "CL_INVALID_GL_OBJECT", "CL_INVALID_BUFFER_SIZE", "CL_INVALID_MIP_LEVEL", "CL_INVALID_GLOBAL_WORK_SIZE", }; const int errorCount = sizeof(errorString) / sizeof(errorString[0]); const int index = -error; return (index >= 0 && index < errorCount) ? errorString[index] : ""; } class Program { std::ifstream fichierSource; cl_int i; cl::Kernel noyau; cl::Buffer parametres[10]; cl::Buffer resultat; int tailleResultat; int nbPara=0; cl::Context contexte; cl::CommandQueue listeCmd; cl::Device gpu; cl_int err; public : Program(Contexte, std::string, std::string ); void init(Contexte, std::string, std::string ); template void initPara( T para, int taille, int sens); template void initPara(T para, int taille, int sens, Args... args); template void initPara(T para); template void initPara(T para, Args... args); template void execute(int dim, int nbPcs, int nbGroupe, T resul); //~Program(); }; Program::Program(Contexte enviro, std::string nomFichier, std::string nomKernel) { init(enviro, nomFichier, nomKernel); } void Program::init(Contexte enviro, std::string nomFichier, std::string nomKernel) { contexte = enviro.obtenirContexte(); listeCmd = enviro.obtenirCmd(); gpu = enviro.obtenirDevice(); fichierSource.open(nomFichier); // Chargement du code source du noyau */ std::string code((std::istreambuf_iterator(fichierSource)), std::istreambuf_iterator()); cl::Program::Sources source(1, std::make_pair(code.c_str(), code.length()+1)); // Association du code source au contexte cl::Program program = cl::Program(contexte, source); // On compile le programme err =program.build(contexte.getInfo()); std::cout << "program.build: " << oclErrorString(err) << std::endl; if (err != CL_SUCCESS){ std::cout << "Build Status: " << program.getBuildInfo(gpu) << std::endl; std::cout << "Build Options:\t" << program.getBuildInfo(gpu) << std::endl; std::cout << "Build Log:\t " << program.getBuildInfo(gpu) << std::endl; } // Création du noyau exécutable noyau = cl::Kernel(program, nomKernel.c_str(), &err); std::cout << " kernel " << err << std::endl; } template void Program::initPara(T para, int taille, int sens) { parametres[nbPara] = cl::Buffer(contexte, sens , taille * sizeof(*para), NULL, &err); std::cout << "buffer = " << err << " , taille = " << sizeof(*para)<< std::endl; if (sens == ENTREE) { std::cout << "Ecriture du tampon de taille " << taille << std::endl; err = listeCmd.enqueueWriteBuffer(parametres[nbPara], CL_TRUE, 0, taille*sizeof(*para), para); std::cout << "Ecriture du tampon de taille " << taille << std::endl; } else if (sens == SORTIE) { resultat = parametres[nbPara]; tailleResultat = taille*sizeof(*para); } else if (sens == ES) { err = listeCmd.enqueueWriteBuffer(parametres[nbPara], CL_TRUE, 0, taille*sizeof(*para), para); } std::cout << " noyau.setArg(" << nbPara << ", " << ")" << std::endl; err = noyau.setArg(nbPara, parametres[nbPara]); std::cout << "setarg = " << err << std::endl; std::cout << " No P = " << nbPara << " , Taille = " << sizeof(*para)<< " :: "<< tailleResultat << std::endl; nbPara++; } template void Program::initPara(T para, int taille, int sens, Args... args) { initPara(para, taille, sens); initPara(args...); } template void Program::initPara(T para) { std::cout << " noyau.setArg(" << nbPara << ", " << para << ")" << std::endl; err = noyau.setArg(nbPara, para); nbPara++; } template void Program::initPara(T para, Args... args) { initPara(para); initPara(args...); } template void Program::execute(int dim, int nbPcs, int nbGroupe, T resul) { if (dim == 1) { if (nbGroupe == 0) err = listeCmd.enqueueNDRangeKernel(noyau, cl::NullRange, cl::NDRange(nbPcs), cl::NullRange); else err = listeCmd.enqueueNDRangeKernel(noyau, cl::NullRange, cl::NDRange(nbPcs), cl::NDRange(nbPcs/nbGroupe)); std::cout<< "Execution : " << err<< std::endl; listeCmd.finish(); std::cout << "Exécution terminée........" << std::endl; err = listeCmd.enqueueReadBuffer(resultat, CL_TRUE, 0, tailleResultat, resul); std::cout<< err<< std::endl; } else if (dim == 2) { err = listeCmd.enqueueNDRangeKernel(noyau, cl::NullRange, cl::NDRange(nbPcs, nbPcs), cl::NDRange(nbGroupe,nbGroupe)); std::cout<< "Execution : " << err<< std::endl; listeCmd.finish();std::cout << "Exécution terminée................" << std::endl; err = listeCmd.enqueueReadBuffer(resultat, CL_TRUE, 0, tailleResultat, resul); std::cout<< err<< std::endl; } else if (dim == 3) { std::cout << "On a trois dimension......" << std::endl; err = listeCmd.enqueueNDRangeKernel(noyau, cl::NullRange, cl::NDRange(nbPcs, nbPcs, nbPcs), cl::NDRange(nbGroupe, nbGroupe, nbGroupe)); std::cout<< "Execution : " << err<< std::endl; std::cout << "resul = " << resul << std::endl; std::cout << "Taille = " << tailleResultat << std::endl; listeCmd.finish();std::cout << "Exécution terminée................" << std::endl; err = listeCmd.enqueueReadBuffer(resultat, CL_TRUE, 0, tailleResultat, resul); std::cout<< err<< std::endl; } } #endif //_OPENCL_PROGRAM_H_