/*! \brief Reads kernel functions from a string into this Program. * * The string object can contain multiple OpenCL kernel * functions. It deletes all comments and if the kernels * are templated, it substitutes the template parameter * with the provided types. For each Kernel function * a Kernel object is built and stored within a map. * The map stores the name of the kernel function and * the corresponding function. * Note that DEFINES are not supported yet. */ ocl::Program& ocl::Program::operator << (const std::string &k) { std::string kernels = k; eraseComments(kernels); //DEBUG_COMMENT(kernels); size_t pos = 0; while(pos < kernels.npos){ const std::string& next = nextKernel(kernels, pos); if(next.empty()) return *this; pos += next.length(); if(_types.empty() || !ocl::Kernel::templated(next)){ ocl::Kernel *kernel = new ocl::Kernel(*this, next); if(this->isBuilt()) kernel->create(); //DEBUG_COMMENT("Creating kernel " << kernel->name() << std::endl << kernel->toString() ); _kernels[kernel->name()] = kernel; continue; } for(utl::Types::const_iterator it = _types.begin(); it != _types.end(); ++it) { const utl::Type &type = **it; ocl::Kernel *kernel = new ocl::Kernel(*this, next, type); if(this->isBuilt()) kernel->create(); //DEBUG_COMMENT("Creating kernel " << kernel->name() << std::endl << kernel->toString() ); _kernels[kernel->name()] = kernel; } } return *this; }
/*! \brief Reads kernel functions from a string into this Program. * * The string object can contain multiple OpenCL kernel * functions. It deletes all comments and if the kernels * are templated, it substitutes the template parameter * with the provided types. For each Kernel function * a Kernel object is built and stored within a map. * The map stores the name of the kernel function and * the corresponding function. * Note that DEFINES are not supported yet. */ ocl::Program& ocl::Program::operator << (const std::string &k) { // std::cout << "kernels: " << _kernels.size() << " blocks: " << commonCodeBlocks_.size() << std::endl; // if ( _kernels.empty() ) // { // commonCodeBlocks_.resize( 0 ); // } std::string kernels = k; //#if 0 // For now disable comment removal as we need it to play a trick on the AMD compiler. eraseComments(kernels); //#endif size_t pos = 0; while(pos < kernels.npos){ const std::string next = nextKernel(kernels, pos); if(next.empty()) { commonCodeBlocks_.push_back( kernels.substr( pos ) ); break; } pos += next.length() + commonCodeBlocks_.back().length(); // std::cout << "COMMON CODE: " << commonCodeBlocks_.back(); // std::cout << "KERNEL CODE: " << next << std::endl; if(_types.empty() || !ocl::Kernel::templated(next)){ std::unique_ptr< ocl::Kernel > kernel( new ocl::Kernel(*this, next) ); if(this->isBuilt()) kernel->create(); auto t = std::find_if( _kernels.begin(), _kernels.end(), [&kernel]( std::unique_ptr< Kernel > const& k ){ return kernel->name() == k->name(); } ); if ( t != _kernels.end() ) { t->swap( kernel ); } else { _kernels.push_back( std::move( kernel ) ); } continue; } for(utl::Types::const_iterator it = _types.begin(); it != _types.end(); ++it) { const utl::Type& type = **it; std::unique_ptr< ocl::Kernel > kernel( new ocl::Kernel(*this, next, type) ); if(this->isBuilt()) { kernel->create(); } Kernels::iterator t = std::find_if( _kernels.begin(), _kernels.end(), [&kernel]( std::unique_ptr< Kernel > const& k ){ return kernel->name() == k->name(); } ); if ( t != _kernels.end() ) { t->swap( kernel ); } else { _kernels.push_back( std::move( kernel ) ); } // "Invent" common code blocks for kernels being generated by the type system. if ( /*std::distance(it, _types.begin()) > 1*/ it != _types.begin() ) { commonCodeBlocks_.push_back("\n"); } } } commonCodeBlocks_.push_back( "" ); // std::cout << "Printing Program in StreamOperator:" << std::endl; // this->print(); // std::cout << "-----------------------------------" << std::endl; checkConstraints(); return *this; }