/** * @brief Add a list of kernel files to internal storage * * Specialized inserter of images into exist container. * * @param klist List to add to existing collection */ void Kernels::addKernels(const KernelList &klist) { copy(klist.begin(), klist.end(), back_inserter(_kernels)); return; }
//------------------------------------------------------------------------ // write stringified cl source wrapped in function that also builds it //------------------------------------------------------------------------ void GenerateWrappers(const string& in_inFileName, const string& in_outFileName, const StringList& in_includePaths) { // read the whole source file in as a single string ifstream inFile(in_inFileName.c_str()); if (!inFile.is_open()) { string error("File not found: "); error += in_inFileName; ReturnError(error); } string src((std::istreambuf_iterator<char>(inFile)), std::istreambuf_iterator<char>()); inFile.close(); StringList sources; // list of source strings, the original and all #includes KernelList kernels; // kernels and their arguments // scan through source for kernels and #includes // recursively search all included files ProcessSource(src, in_includePaths, sources, kernels); string header = GetHeader(in_outFileName); string getProgramName = CLU_PREFIX "Get_" + header; ofstream outFile(in_outFileName.c_str()); if (!outFile.is_open()) { string error("File could not be opened for writing: "); error += in_outFileName; ReturnError(error); } // helpful comments if( g_generateCPP ) { outFile << "/* CLU GENERATED */" << endl << "/* All structures and functions generated by CLU start with " << CLU_PREFIX << " */" << endl << "/*" << endl << "Typical Usage:" << endl << " auto kernelFunctorName = clugCreate_MyKernelName();" << endl << " kernelFunctorName(" << endl << " cl::EnqueueArgs(cl::NDRange(numElements), cl::NDRange(numElements)), ...);" << endl << endl << "Exports:" << endl; for_each(kernels.begin(), kernels.end(), WriteCPPExports(outFile)); } else { outFile << "/* CLU GENERATED */" << endl << "/* All structures and functions generated by CLU start with " << CLU_PREFIX << " */" << endl << "/*" << endl << "Typical Usage:" << endl << endl << " " CLU_PREFIX "MyKernelName s = " CLU_PREFIX_CREATE "MyKernelName(0);" << endl << " clu_enqueue_params params = CLU_DEFAULT_PARAMS;" << endl << " params.nd_range = CLU_ND1(bufferLength);" << endl << " status = " CLU_PREFIX_ENQUEUE "MyKernel(s, ¶ms, ...);" << endl << endl << "Exports:" << endl; for_each(kernels.begin(), kernels.end(), WriteExports(outFile)); } outFile << "*/" << endl << endl; // #pragma once if( g_generateCPP ) { outFile << "#include <CL/cl.hpp>" << endl << "#include <functional>" << endl << "#ifndef __" << header.c_str() << endl << "#define __" << header.c_str() << endl << endl; // function to build program from stringified sources outFile << "cl::Program " << getProgramName << "(const cl::Context &creationContext)" << endl << "{" << endl << " static const char* src[" << sources.size() << "] = {"; for_each(sources.begin(), sources.end(), WriteSourceString(outFile)); outFile << endl << " };" << endl; // TODO: Expand to make this accept more than one source string outFile << " cl::Program::Sources sourceList;" << endl; for( unsigned int i = 0; i < sources.size(); ++i ) { outFile << " sourceList.push_back(" << endl << " std::pair<const char*, ::size_t>(src[" << i << "], strlen(src[" << i << "]))"; if( i < (sources.size() - 1) ) { outFile << ", " << endl; } } outFile << ");" << endl; outFile << " cl::Program program = cl::Program(creationContext, sourceList);" << endl << " program.build();" << endl << " return program;" << endl << "}" << endl << endl; for_each(kernels.begin(), kernels.end(), WriteCPPKernelWrapper(outFile, getProgramName)); outFile << "#endif" << endl << endl; } else { outFile << "#include <clu.h>" << endl << "#ifndef __" << header.c_str() << endl << "#define __" << header.c_str() << endl << endl; // function to build program from stringified sources outFile << "/* This function is shared by all " CLU_PREFIX_CREATE "* functions below */" << endl << "CLU_INLINE cl_program " << getProgramName << "(cl_int* out_pStatus)" << endl << "{" << endl << " static const char* src[" << sources.size() << "] = {"; for_each(sources.begin(), sources.end(), WriteSourceString(outFile)); outFile << endl << " };" << endl << " /* CLU will only build this program the first time */" << endl << " /* CLU will release this program upon shutdown (cluRelease) */" << endl << // pass a flag to the build API so it will know to manage the lifetime of the resulting cl_program " cl_program program = cluBuildSourceArray(" << sources.size() << ", src, 0, \"" << CLU_MAGIC_BUILD_FLAG << "\", out_pStatus);" << endl << " return program;" << endl << "}" << endl << endl; for_each(kernels.begin(), kernels.end(), WriteKernelWrapper(outFile, getProgramName)); outFile << "#endif" << endl << endl; } outFile.close(); if (g_verbose) { cerr << "kernels found: "; for (KernelList::iterator i = kernels.begin(); i != kernels.end(); i++) { if (i != kernels.begin()) cerr << ", "; cerr << i->m_kernelName; } cerr << endl; } }