14 #if ( SETTING_OPENCL != 0 )
24 #include <boost/iostreams/device/mapped_file.hpp>
44 std::shared_ptr< State >
const& pState,
45 char const*
const*
const filenames,
46 char const*
const options,
47 char const*
const logFilename
51 cl_int result = CL_SUCCESS;
52 cl_device_id
const deviceID = m_pState->DeviceID();
55 std::vector< boost::iostreams::mapped_file_source > fileMaps;
56 std::vector< boost::iostreams::mapped_file_source::size_type > fileLengths;
57 std::vector< char const* > fileContents;
58 for (
unsigned int ii = 0; filenames[ ii ] != NULL; ++ii ) {
60 fileMaps.push_back( boost::iostreams::mapped_file_source( filenames[ ii ] ) );
61 if ( ! fileMaps.back().is_open() )
62 THROW_EXCEPTION(
"boost::iostreams::mapped_file_source constructor failed!" );
63 fileLengths.push_back( fileMaps.back().size() );
64 fileContents.push_back( fileMaps.back().data() );
66 assert( fileMaps.size() == fileLengths.size() );
67 assert( fileMaps.size() == fileContents.size() );
70 m_program.reset( clCreateProgramWithSource( m_pState->Context(), fileMaps.size(), fileContents.data(), fileLengths.data(), &result ) );
71 if ( result != CL_SUCCESS )
75 result = clBuildProgram( m_program.get(), 1, &deviceID, options, NULL, NULL );
76 if ( logFilename != NULL ) {
78 cl_build_status status = CL_BUILD_NONE;
79 cl_int
const statusResult = clGetProgramBuildInfo( m_program.get(), deviceID, CL_PROGRAM_BUILD_STATUS,
sizeof( status ), &status, NULL );
81 size_t optionsLength = 0;
82 std::unique_ptr< char[] > options;
83 cl_int optionsResult = clGetProgramBuildInfo( m_program.get(), deviceID, CL_PROGRAM_BUILD_OPTIONS, 0, NULL, &optionsLength );
84 if ( ( optionsResult == CL_SUCCESS ) && ( optionsLength > 1 ) ) {
86 options.reset(
new char[ optionsLength ] );
87 optionsResult = clGetProgramBuildInfo( m_program.get(), deviceID, CL_PROGRAM_BUILD_OPTIONS, optionsLength, options.get(), &optionsLength );
88 if ( ( optionsResult == CL_SUCCESS ) && ( optionsLength > 1 ) ) {
90 bool printable =
false;
91 for (
unsigned int ii = 0; ( ! printable ) && ( ii < optionsLength ); ++ii )
92 printable |= ( std::isprint( options[ ii ] ) != 0 );
101 size_t logLength = 0;
102 std::unique_ptr< char[] > log;
103 cl_int logResult = clGetProgramBuildInfo( m_program.get(), deviceID, CL_PROGRAM_BUILD_LOG, 0, NULL, &logLength );
104 if ( ( logResult == CL_SUCCESS ) && ( logLength > 1 ) ) {
106 log.reset(
new char[ logLength ] );
107 logResult = clGetProgramBuildInfo( m_program.get(), deviceID, CL_PROGRAM_BUILD_LOG, logLength, log.get(), &logLength );
108 if ( ( logResult == CL_SUCCESS ) && ( logLength > 1 ) ) {
110 bool printable =
false;
111 for (
unsigned int ii = 0; ( ! printable ) && ( ii < logLength ); ++ii )
112 printable |= ( std::isprint( log[ ii ] ) != 0 );
121 if ( ( ( statusResult == CL_SUCCESS ) && ( status != CL_BUILD_SUCCESS ) ) || ( ( logResult == CL_SUCCESS ) && ( logLength > 1 ) ) ) {
123 std::ofstream logFile( logFilename, std::ios_base::out | std::ios_base::trunc );
124 if ( ! logFile.is_open() )
127 bool printed =
false;
128 if ( statusResult == CL_SUCCESS ) {
130 char const* message =
"<unknown status>";
132 case CL_BUILD_NONE: { message =
"CL_BUILD_NONE";
break; }
133 case CL_BUILD_ERROR: { message =
"CL_BUILD_ERROR";
break; }
134 case CL_BUILD_SUCCESS: { message =
"CL_BUILD_SUCCESS";
break; }
135 case CL_BUILD_IN_PROGRESS: { message =
"CL_BUILD_IN_PROGRESS";
break; }
137 logFile <<
"Build status = " << message <<
" (code=" << status <<
')' << std::endl;
140 if ( ( optionsResult == CL_SUCCESS ) && ( optionsLength > 1 ) ) {
142 logFile <<
"Build options = \"" <<
CollapseWhitespace( options.get() ) <<
'"' << std::endl;
145 if ( ( logResult == CL_SUCCESS ) && ( logLength > 1 ) ) {
148 logFile << std::endl << std::endl;
151 "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << std::endl <<
152 " Build log" << std::endl <<
153 "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << std::endl <<
158 int iiEnd = logLength - 1;
159 for ( ; ( ii < iiEnd ) && ( ! std::isprint( log[ ii ] ) ); ++ii );
160 for ( ; ( iiEnd > ii ) && ( ! std::isprint( log[ iiEnd ] ) ); --iiEnd );
161 logFile.write( log.get() + ii, 1 + iiEnd - ii );
163 logFile << std::endl;
166 for (
unsigned int ii = 0; ii < fileMaps.size(); ++ii ) {
169 logFile << std::endl << std::endl;
172 "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << std::endl <<
173 " Source code - \"" << filenames[ ii ] <<
'"' << std::endl <<
174 "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-" << std::endl <<
179 int jjEnd = fileLengths[ ii ];
180 for ( ; ( jj < jjEnd ) && ( ! std::isprint( fileContents[ ii ][ jj ] ) ); ++jj );
181 for ( ; ( jjEnd > jj ) && ( ! std::isprint( fileContents[ ii ][ jjEnd ] ) ); --jjEnd );
182 logFile.write( fileContents[ ii ] + jj, 1 + jjEnd - jj );
184 logFile << std::endl;
189 if ( result != CL_SUCCESS )
201 #endif // SETTING_OPENCL