43 : _name(
std::move(name)), _source(
std::move(source))
66 std::vector<GLchar> log(length);
85 build_options.c_str(),
103 std::vector<GLchar> log(length);
106 #ifdef ARM_COMPUTE_DEBUG_ENABLED 107 std::istringstream
ss(_source);
108 std::stringstream output_stream;
113 while(std::getline(ss, line,
'\n'))
115 output_stream << std::setw(6) << line_num <<
": " << line << std::endl;
119 << output_stream.rdbuf());
131 : _name(), _program(), _shader_arguments(), _shader_params_ubo_name(), _shader_params_binding_point(), _shader_params_index(), _shader_params_size()
141 : _name(
std::move(name)),
144 _shader_params_ubo_name(0),
145 _shader_params_binding_point(0),
146 _shader_params_index(0),
147 _shader_params_size(0)
149 _shader_arguments.clear();
179 ARM_COMPUTE_ERROR_ON_MSG_VAR((_shader_params_size != (
int)(_shader_arguments.size() *
sizeof(_shader_arguments[0]))),
"Arguments size (%zu) is not equal to shader params block size (%d)",
180 _shader_arguments.size() *
sizeof(_shader_arguments[0]), _shader_params_size);
189 const std::map<std::string, std::string> GCKernelLibrary::_shader_program_map =
191 {
"absdiff",
"absdiff.cs" },
192 {
"tensorshift",
"tensor_shift.cs" },
193 {
"direct_convolution1x1",
"direct_convolution1x1.cs" },
194 {
"direct_convolution3x3",
"direct_convolution3x3.cs" },
195 {
"direct_convolution5x5",
"direct_convolution5x5.cs" },
196 {
"pooling_layer_2",
"pooling_layer.cs" },
197 {
"pooling_layer_3",
"pooling_layer.cs" },
198 {
"pooling_layer_7",
"pooling_layer.cs" },
199 {
"pooling_layer_3_optimized",
"pooling_layer.cs" },
200 {
"pooling_layer_n",
"pooling_layer.cs" },
201 {
"fill_image_borders_replicate",
"fill_border.cs" },
202 {
"fill_image_borders_constant",
"fill_border.cs" },
203 {
"gemm_accumulate_biases",
"gemm.cs" },
204 {
"gemm_interleave4x4",
"gemm.cs" },
205 {
"gemm_ma",
"gemm.cs" },
206 {
"gemm_mm_interleaved_transposed",
"gemm.cs" },
207 {
"gemm_mm_floating_point",
"gemm.cs" },
208 {
"gemm_transpose1x4",
"gemm.cs" },
209 {
"reshape_to_columns",
"convolution_layer.cs" },
210 {
"im2col_kernel3x3_padx0_pady0",
"convolution_layer.cs" },
211 {
"im2col_generic",
"convolution_layer.cs" },
212 {
"im2col_reduced",
"convolution_layer.cs" },
213 {
"col2im",
"convolution_layer.cs" },
214 {
"transpose",
"transpose.cs" },
215 {
"activation_layer",
"activation_layer.cs" },
216 {
"softmax_layer_max",
"softmax_layer.cs" },
217 {
"softmax_layer_shift_exp_sum",
"softmax_layer.cs" },
218 {
"softmax_layer_norm",
"softmax_layer.cs" },
219 {
"pixelwise_mul_float",
"pixelwise_mul_float.cs" },
220 {
"normalization_layer",
"normalization_layer.cs" },
221 {
"batchnormalization_layer",
"batchnormalization_layer.cs" },
222 {
"concatenate_depth",
"concatenate.cs" },
223 {
"dropout",
"dropout.cs" },
224 {
"normalize_planar_yuv_layer",
"normalize_planar_yuv_layer.cs" },
225 {
"scale_nearest_neighbour",
"scale.cs" },
226 {
"arithmetic_add",
"arithmetic_add.cs" },
227 {
"depthwise_convolution_3x3",
"depthwise_convolution3x3.cs" },
230 const std::map<std::string, std::string> GCKernelLibrary::_program_source_map =
232 #ifdef EMBEDDED_KERNELS 235 #include "./cs_shaders/helpers_cs.hembed" 238 "activation_layer_helpers_cs.h",
239 #include "./cs_shaders/activation_layer_helpers_cs.hembed" 243 #include "./cs_shaders/absdiff.csembed" 247 #include "./cs_shaders/tensor_shift.csembed" 250 "convolution_layer.cs",
251 #include "./cs_shaders/convolution_layer.csembed" 254 "direct_convolution1x1.cs",
255 #include "./cs_shaders/direct_convolution1x1.csembed" 258 "direct_convolution3x3.cs",
259 #include "./cs_shaders/direct_convolution3x3.csembed" 262 "direct_convolution5x5.cs",
263 #include "./cs_shaders/direct_convolution5x5.csembed" 267 #include "./cs_shaders/pooling_layer.csembed" 271 #include "./cs_shaders/fill_border.csembed" 275 #include "./cs_shaders/gemm.csembed" 279 #include "./cs_shaders/transpose.csembed" 282 "activation_layer.cs",
283 #include "./cs_shaders/activation_layer.csembed" 287 #include "./cs_shaders/softmax_layer.csembed" 290 "pixelwise_mul_float.cs",
291 #include "./cs_shaders/pixelwise_mul_float.csembed" 294 "normalization_layer.cs",
295 #include "./cs_shaders/normalization_layer.csembed" 298 "batchnormalization_layer.cs",
299 #include "./cs_shaders/batchnormalization_layer.csembed" 303 #include "./cs_shaders/concatenate.csembed" 307 #include "./cs_shaders/dropout.csembed" 310 "normalize_planar_yuv_layer.cs",
311 #include "./cs_shaders/normalize_planar_yuv_layer.csembed" 315 #include "./cs_shaders/scale.csembed" 319 #include "./cs_shaders/arithmetic_add.csembed" 322 "depthwise_convolution3x3.cs",
323 #include "./cs_shaders/depthwise_convolution3x3.csembed" 329 : _display(EGL_NO_DISPLAY), _context(EGL_NO_CONTEXT), _frame_buffer(0), _tex_rt(0), _shader_path(
"./"), _programs_map(), _built_programs_map()
336 return _kernel_library;
342 _shader_path = std::move(shader_path);
347 eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, _context);
353 _shader_path = shader_path;
369 auto shader_program_it = _shader_program_map.find(shader_name);
371 if(_shader_program_map.end() == shader_program_it)
377 const std::string program_name = shader_program_it->second;
378 const std::string
build_options = stringify_set(build_options_set);
379 const std::string built_program_name = program_name +
"_" +
build_options;
380 auto built_program_it = _built_programs_map.find(built_program_name);
384 if(_built_programs_map.end() != built_program_it)
387 kernel = built_program_it->second;
391 GCProgram program = load_program(program_name);
393 std::string source_name = _shader_path + shader_program_it->second;
402 kernel =
GCKernel(shader_name, gles_program);
405 _built_programs_map.emplace(built_program_name, kernel);
416 std::string GCKernelLibrary::preprocess_shader(
const std::string &shader_source)
const 418 enum class ParserStage
421 SKIP_COMMENTS = FIRST,
427 std::function<std::string(const std::string &, ParserStage, int)> cs_parser;
428 cs_parser = [&](
const std::string &
src, ParserStage stage, int) -> std::string
432 if(stage == ParserStage::LAST || std::regex_match(src, std::regex(R
"(\s*)"))) 436 auto next_stage =
static_cast<ParserStage
>(
static_cast<int>(stage) + 1);
438 std::string search_pattern;
441 case ParserStage::SKIP_COMMENTS:
442 search_pattern = R
"((/\*([^*]|\n|(\*+([^*/]|\n)))*\*+/)|(//.*))"; 444 case ParserStage::RESOLVE_INCLUDES:
445 search_pattern = R
"rgx((?:^|\n)[ \t]*#include "(.*)")rgx"; 451 std::regex search_regex(search_pattern);
453 ptrdiff_t parsed_pos = 0;
454 if(std::regex_search(src, match, search_regex))
457 dst.append(cs_parser(src.substr(0, match.position()), next_stage, 0));
458 parsed_pos = match.position() + match.length();
463 case ParserStage::RESOLVE_INCLUDES:
467 const std::string source_name = _shader_path + match.str(1);
468 dst.append(cs_parser(
read_file(source_name,
false), ParserStage::FIRST, 0));
471 case ParserStage::SKIP_COMMENTS:
473 dst.append(match.str());
478 dst.append(cs_parser(src.substr(parsed_pos, src.length() - parsed_pos), next_stage, 0));
483 return cs_parser(shader_source, ParserStage::FIRST, 0);
486 const GCProgram &GCKernelLibrary::load_program(
const std::string &program_name)
const 488 const auto program_it = _programs_map.find(program_name);
490 if(program_it != _programs_map.end())
492 return program_it->second;
497 #ifdef EMBEDDED_KERNELS 498 const auto program_source_it = _program_source_map.find(program_name);
500 if(_program_source_map.end() == program_source_it)
505 program =
GCProgram(program_name, program_source_it->second);
508 std::string source_name = _shader_path + program_name;
509 if(std::ifstream(source_name).is_open())
520 const auto new_program = _programs_map.emplace(program_name, std::move(program));
522 return new_program.first->second;
537 for(
auto &program : _built_programs_map)
539 static_cast<GCKernel>(program.second).cleanup();
548 std::string GCKernelLibrary::stringify_set(
const StringSet &s)
const 550 std::string concat_set;
553 for(
const auto &el : s)
555 concat_set += el +
"\n";
void GL_APIENTRY glGenTextures(GLsizei n, GLuint *textures)
GCProgram()
Default constructor.
#define ARM_COMPUTE_GL_CHECK(x)
EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)
void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint *textures)
void set_context(EGLDisplay dpy, EGLContext ctx)
Sets display and context to create kernel.
void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint *buffers)
void GL_APIENTRY glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog)
GLuint compile_shader(const std::string &build_options)
Compile shader.
void GL_APIENTRY glCompileShader(GLuint shader)
std::string name() const
Returns kernel name.
#define ARM_COMPUTE_ERROR_VAR(msg,...)
Print the given message then throw an std::runtime_error.
void update_shader_params()
Update shader params.
std::stringstream ss(mlgo_str)
void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint *params)
#define ARM_COMPUTE_ERROR_ON_MSG_VAR(cond, msg,...)
void use()
Use current program.
SimpleTensor< float > src
Copyright (c) 2017-2021 Arm Limited.
void GL_APIENTRY glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
void set_shader_params_binding_point(unsigned int binding)
Set shader params binding point.
void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
std::string name() const
Returns program name.
void cleanup()
Clean up program and ubo.
void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)
void GL_APIENTRY glDeleteProgram(GLuint program)
void GL_APIENTRY glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
#define ARM_COMPUTE_LOG_INFO_MSG_WITH_FORMAT_CORE(fmt,...)
Log information level formatted message to the core system logger.
GLuint GL_APIENTRY glGetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
std::string read_file(const std::string &filename, bool binary)
Load an entire file in memory.
void set_shader_path(const std::string &shader_path)
Sets the path that the shaders reside in.
void GL_APIENTRY glUseProgram(GLuint program)
Manages all the GLES kernels compilation and caching, provides accessors for the GLES Context...
void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
std::set< std::string > build_options
void GL_APIENTRY glGenBuffers(GLsizei n, GLuint *buffers)
GCKernelLibrary()
Default Constructor.
GLuint GL_APIENTRY glCreateShader(GLenum type)
~GCKernelLibrary()
Default Destructor.
#define ARM_COMPUTE_LOG_INFO_STREAM_CORE(ss)
Log information level stream to the core system logger.
GLuint link_program(GLuint shader)
Link program.
void GL_APIENTRY glAttachShader(GLuint program, GLuint shader)
void setup_dummy_fbo()
Setup a dummy fbo to workaround an issue on Galaxy S8.
void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
GLuint GL_APIENTRY glCreateProgram()
void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint *params)
void clear_arguments()
Clear shader arguments.
static GCKernelLibrary & get()
Get the static instance of GCKernelLibrary.
void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint *framebuffers)
void init(std::string shader_path="./", EGLDisplay dpy=EGL_NO_DISPLAY, EGLContext ctx=EGL_NO_CONTEXT)
Initialises the kernel library.
void GL_APIENTRY glLinkProgram(GLuint program)
void GL_APIENTRY glDetachShader(GLuint program, GLuint shader)
void GL_APIENTRY glDeleteShader(GLuint shader)
GCKernel create_kernel(const std::string &shader_name, const StringSet &build_options_set={}) const
Creates a kernel from the kernel library.
void GL_APIENTRY glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params)
GCKernel()
Default Constructor.
void unuse()
Unuse current program.
void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog)