• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2021 Huawei Technologies Co., Ltd
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "tools/common/opengl_util.h"
18 #include <cstdlib>
19 #include <algorithm>
20 
21 namespace mindspore {
22 namespace OpenGL {
23 #if defined(GPU_OPENCL) && defined(__ANDROID__) && defined(ENABLE_ARM64)
24 const char *g_glsl_host_to_device_2d =
25   "#version 320 es\n"
26   "#define PRECISION highp\n"
27   "precision PRECISION float;\n"
28   "#define FORMAT rgba32f\n"
29   "layout(FORMAT, binding=0) writeonly uniform PRECISION image2D uImage;\n"
30   "layout(binding=1) readonly buffer SSBO {\n"
31   "    float data[];\n"
32   "} uInBuffer;\n"
33   "layout(location = 2) uniform int uWidth;\n"
34   "layout(location = 3) uniform int uHeight;\n"
35   "layout(location = 4) uniform int uChannel;\n"
36   "layout (local_size_x = 4, local_size_y = 4, local_size_z = 1) in;\n"
37   "void main()\n"
38   "{\n"
39   "    ivec3 pos = ivec3(gl_GlobalInvocationID);\n"
40   "    if (pos.x < uWidth && pos.y < uHeight)\n"
41   "    {\n"
42   "        vec4 color;\n"
43   "        color.r = uInBuffer.data[pos.y*uWidth*uChannel + pos.x*uChannel + 0];\n"
44   "        color.g = uInBuffer.data[pos.y*uWidth*uChannel + pos.x*uChannel + 1];\n"
45   "        color.b = uInBuffer.data[pos.y*uWidth*uChannel + pos.x*uChannel + 2];\n"
46   "        color.a = uInBuffer.data[pos.y*uWidth*uChannel + pos.x*uChannel + 3];\n"
47   "        imageStore(uImage, pos.xy, color);\n"
48   "    }\n"
49   "}\n";
50 
51 const char *g_glsl_host_to_device_3d =
52   "#version 320 es\n"
53   "#define PRECISION highp\n"
54   "precision PRECISION float;\n"
55   "#define FORMAT rgba32f\n"
56   "layout(FORMAT, binding=0) writeonly uniform PRECISION image3D uImage;\n"
57   "layout(binding=1) readonly buffer SSBO {\n"
58   "    float data[];\n"
59   "} uInBuffer;\n"
60   "layout(location = 2) uniform int uWidth;\n"
61   "layout(location = 3) uniform int uHeight;\n"
62   "layout(location = 4) uniform int uChannel;\n"
63   "layout (local_size_x = 4, local_size_y = 4, local_size_z = 1) in;\n"
64   "void main()\n"
65   "{\n"
66   "    ivec3 pos = ivec3(gl_GlobalInvocationID);\n"
67   "    if (pos.x < uWidth && pos.y < uHeight)\n"
68   "    {\n"
69   "        vec4 color;\n"
70   "        int z = pos.z*4;\n"
71   "        color.r = uInBuffer.data[pos.y*uWidth*uChannel + pos.x*uChannel + (z+0)];\n"
72   "        color.g = uInBuffer.data[pos.y*uWidth*uChannel + pos.x*uChannel + (z+1)];\n"
73   "        color.b = uInBuffer.data[pos.y*uWidth*uChannel + pos.x*uChannel + (z+2)];\n"
74   "        color.a = uInBuffer.data[pos.y*uWidth*uChannel + pos.x*uChannel + (z+3)];\n"
75   "        imageStore(uImage, pos, color);\n"
76   "    }\n"
77   "}\n";
78 
79 const char *g_glsl_device_to_host_2d =
80   "#version 320 es\n"
81   "#define PRECISION highp\n"
82   "precision PRECISION float;\n"
83   "#define FORMAT rgba32f\n"
84   "layout(FORMAT, binding=0) readonly uniform PRECISION image2D uImage;\n"
85   "layout(binding=1) writeonly buffer destBuffer{\n"
86   "    float data[];\n"
87   "} uOutBuffer;\n"
88   "layout(location = 2) uniform int uWidth;\n"
89   "layout(location = 3) uniform int uHeight;\n"
90   "layout(location = 4) uniform int uChannel;\n"
91   "layout (local_size_x = 4, local_size_y = 4, local_size_z = 1) in;\n"
92   "#define UP_DIV(x, y) (((x) + (y) - (1)) / (y))\n"
93   "void main()\n"
94   "{\n"
95   "    ivec3 pos = ivec3(gl_GlobalInvocationID);\n"
96   "    if (pos.x < uWidth  && pos.y < uHeight)\n"
97   "    {\n"
98   "        vec4 color = imageLoad(uImage, ivec2(pos.x * UP_DIV(uChannel, 4) + pos.z, pos.y));\n"
99   "        int z = pos.z*4;\n"
100   "         for (int i = 0; i < 4; i++) {\n"
101   "            if (z + i < uChannel) {\n"
102   "              uOutBuffer.data[pos.y*uWidth*uChannel+pos.x*uChannel+(z+i)] = color[i];\n"
103   "            } \n"
104   "         } \n"
105   "    }\n"
106   "}\n";
107 
108 const char *g_glsl_device_to_host_3d =
109   "#version 320 es\n"
110   "#define PRECISION highp\n"
111   "precision PRECISION float;\n"
112   "#define FORMAT rgba32f\n"
113   "layout(FORMAT, binding=0) readonly uniform PRECISION image3D uImage;\n"
114   "layout(binding=1) writeonly buffer destBuffer{\n"
115   "    float data[];\n"
116   "} uOutBuffer;\n"
117   "layout(location = 2) uniform int uWidth;\n"
118   "layout(location = 3) uniform int uHeight;\n"
119   "layout(location = 4) uniform int uChannel;\n"
120   "layout (local_size_x = 4, local_size_y = 4, local_size_z = 1) in;\n"
121   "void main()\n"
122   "{\n"
123   "    ivec3 pos = ivec3(gl_GlobalInvocationID);\n"
124   "    if (pos.x < uWidth && pos.y < uHeight)\n"
125   "    {\n"
126   "        vec4 color = imageLoad(uImage, pos);\n"
127   "        int z = pos.z*4;\n"
128   "        uOutBuffer.data[pos.y*uWidth*uChannel+pos.x*uChannel+(z+0)] = color.r;\n"
129   "        uOutBuffer.data[pos.y*uWidth*uChannel+pos.x*uChannel+(z+1)] = color.g;\n"
130   "        uOutBuffer.data[pos.y*uWidth*uChannel+pos.x*uChannel+(z+2)] = color.b;\n"
131   "        uOutBuffer.data[pos.y*uWidth*uChannel+pos.x*uChannel+(z+3)] = color.a;\n"
132   "    }\n"
133   "}\n";
134 
135 constexpr int kC4Align = 4;
136 constexpr int kWidthIndex = 0;
137 constexpr int kHeightIndex = 1;
138 constexpr int kChannelIndex = 2;
139 
Init()140 bool OpenGLRuntime::Init() {
141   MS_LOG(INFO) << "Rt Init Begin";
142   if (!(eglGetCurrentContext() != EGL_NO_CONTEXT)) {
143     m_display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
144     if (m_display_ == EGL_NO_DISPLAY) {
145       MS_LOG(ERROR) << "eglGetDisplay error";
146       return false;
147     }
148 
149     int majorVersion;
150     int minorVersion;
151     auto glRet = eglInitialize(m_display_, &majorVersion, &minorVersion);
152     if (glRet != EGL_TRUE) {
153       MS_LOG(ERROR) << "eglInitialize error";
154       return false;
155     }
156 
157     EGLint numConfigs;
158     static const EGLint configAttribs[] = {EGL_SURFACE_TYPE,
159                                            EGL_PBUFFER_BIT,
160                                            EGL_RENDERABLE_TYPE,
161                                            EGL_OPENGL_ES2_BIT,
162                                            EGL_RED_SIZE,
163                                            8,
164                                            EGL_GREEN_SIZE,
165                                            8,
166                                            EGL_BLUE_SIZE,
167                                            8,
168                                            EGL_ALPHA_SIZE,
169                                            8,
170                                            EGL_NONE};
171 
172     EGLConfig surfaceConfig;
173     if (!eglChooseConfig(m_display_, configAttribs, &surfaceConfig, 1, &numConfigs)) {
174       eglMakeCurrent(m_display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
175       eglTerminate(m_display_);
176       m_display_ = EGL_NO_DISPLAY;
177       MS_LOG(ERROR) << "eglChooseConfig error";
178       return false;
179     }
180 
181     static const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
182     m_context_ = eglCreateContext(m_display_, surfaceConfig, NULL, contextAttribs);
183     static const EGLint surfaceAttribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};
184     m_surface_ = eglCreatePbufferSurface(m_display_, surfaceConfig, surfaceAttribs);
185 
186     glRet = eglMakeCurrent(m_display_, m_surface_, m_surface_, m_context_);
187     if (glRet != EGL_TRUE) {
188       MS_LOG(ERROR) << "eglMakeCurrent error";
189       return false;
190     }
191 
192     eglBindAPI(EGL_OPENGL_ES_API);
193   } else {
194     m_context_ = EGL_NO_CONTEXT;
195     MS_LOG(ERROR) << "eglGetCurrentContext() != EGL_NO_CONTEXT";
196     return false;
197   }
198   MS_LOG(INFO) << "Rt Init End";
199   return true;
200 }
201 
LoadShader(GLenum shaderType,const char * pSource)202 GLuint OpenGLRuntime::LoadShader(GLenum shaderType, const char *pSource) {
203   GLuint shader = glCreateShader(shaderType);
204   if (shader) {
205     glShaderSource(shader, 1, &pSource, NULL);
206     glCompileShader(shader);
207     GLint compiled = 0;
208     glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
209     if (!compiled) {
210       GLint infoLen = 0;
211       glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
212       if (infoLen > 0) {
213         char *buf = reinterpret_cast<char *>(malloc(infoLen));
214         MS_CHECK_TRUE_MSG(buf != nullptr, 0, "Malloc OpenGL Buffer failed");
215         glGetShaderInfoLog(shader, infoLen, NULL, buf);
216         fprintf(stderr, "Could not compile shader %d:\n%s\n", shaderType, buf);
217         free(buf);
218         glDeleteShader(shader);
219         shader = 0;
220       }
221     }
222   }
223   return shader;
224 }
225 
CreateComputeProgram(const char * pComputeSource)226 GLuint OpenGLRuntime::CreateComputeProgram(const char *pComputeSource) {
227   GLuint computeShader = LoadShader(GL_COMPUTE_SHADER, pComputeSource);
228   if (!computeShader) {
229     return 0;
230   }
231 
232   GLuint program = glCreateProgram();
233   if (program) {
234     glAttachShader(program, computeShader);
235     glLinkProgram(program);
236     GLint linkStatus = GL_FALSE;
237     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
238     if (linkStatus != GL_TRUE) {
239       GLint bufLength = 0;
240       glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
241       if (bufLength > 0) {
242         char *buf = reinterpret_cast<char *>(malloc(bufLength));
243         MS_CHECK_TRUE_MSG(buf != nullptr, 0, "Malloc OpenGL Buffer failed");
244         glGetProgramInfoLog(program, bufLength, NULL, buf);
245         fprintf(stderr, "Could not link program:\n%s\n", buf);
246         free(buf);
247       }
248       glDeleteProgram(program);
249       program = 0;
250     }
251   }
252   return program;
253 }
254 
GLCreateSSBO(GLsizeiptr size,void * hostData,GLenum type,GLenum usage)255 GLuint OpenGLRuntime::GLCreateSSBO(GLsizeiptr size, void *hostData, GLenum type, GLenum usage) {
256   MS_ASSERT(size > 0);
257 
258   GLuint ssboBufferID;
259   glGenBuffers(1, &ssboBufferID);
260   OPENGL_CHECK_ERROR;
261 
262   glBindBuffer(type, ssboBufferID);
263   OPENGL_CHECK_ERROR;
264   MS_ASSERT(ssboBufferID > 0);
265 
266   glBufferData(type, size, hostData, usage);
267   OPENGL_CHECK_ERROR;
268 
269   MS_ASSERT(m_ssbo_pool_.count(ssboBufferID) == 0);
270   m_ssbo_pool_[ssboBufferID] = std::make_pair(size, type);
271 
272   return ssboBufferID;
273 }
274 
CopyDeviceSSBOToHost(GLuint ssboBufferID,void * hostData,GLsizeiptr size)275 bool OpenGLRuntime::CopyDeviceSSBOToHost(GLuint ssboBufferID, void *hostData, GLsizeiptr size) {
276   MS_ASSERT(m_ssbo_pool_.count(ssboBufferID) > 0);
277   MS_ASSERT(m_ssbo_pool_[ssboBufferID].first >= size);
278 
279   glBindBuffer(m_ssbo_pool_[ssboBufferID].second, ssboBufferID);
280   OPENGL_CHECK_ERROR;
281 
282   auto ptr = glMapBufferRange(m_ssbo_pool_[ssboBufferID].second, 0, m_ssbo_pool_[ssboBufferID].first, GL_MAP_READ_BIT);
283   OPENGL_CHECK_ERROR;
284 
285   if (ptr != nullptr) {
286     ::memcpy(hostData, ptr, size);
287   }
288 
289   glUnmapBuffer(m_ssbo_pool_[ssboBufferID].second);
290   OPENGL_CHECK_ERROR;
291   return true;
292 }
293 
CopyHostToDeviceSSBO(void * hostData,GLuint ssboBufferID,GLsizeiptr size)294 bool OpenGLRuntime::CopyHostToDeviceSSBO(void *hostData, GLuint ssboBufferID, GLsizeiptr size) {
295   MS_ASSERT(m_ssbo_pool_.count(ssboBufferID) > 0);
296   MS_ASSERT(m_ssbo_pool_[ssboBufferID].first >= size);
297 
298   glBindBuffer(m_ssbo_pool_[ssboBufferID].second, ssboBufferID);
299   OPENGL_CHECK_ERROR;
300 
301   auto ptr = glMapBufferRange(m_ssbo_pool_[ssboBufferID].second, 0, m_ssbo_pool_[ssboBufferID].first, GL_MAP_READ_BIT);
302   OPENGL_CHECK_ERROR;
303 
304   if (ptr != nullptr) {
305     ::memcpy(ptr, hostData, size);
306   }
307 
308   glUnmapBuffer(m_ssbo_pool_[ssboBufferID].second);
309   OPENGL_CHECK_ERROR;
310   return true;
311 }
312 
GLCreateTexture(int w,int h,int c,GLenum TextrueFormat,GLenum target)313 GLuint OpenGLRuntime::GLCreateTexture(int w, int h, int c, GLenum TextrueFormat, GLenum target) {
314   GLuint textureID = 0;
315   if (target == GL_TEXTURE_3D) {
316     MS_ASSERT(w > 0 && h > 0 && c > 0);
317     glGenTextures(1, &textureID);
318     OPENGL_CHECK_ERROR;
319     glBindTexture(target, textureID);
320     OPENGL_CHECK_ERROR;
321     glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
322     OPENGL_CHECK_ERROR;
323     glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
324     OPENGL_CHECK_ERROR;
325     glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
326     OPENGL_CHECK_ERROR;
327     glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
328     OPENGL_CHECK_ERROR;
329     glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
330     OPENGL_CHECK_ERROR;
331 
332     int realW = w;
333     int realH = h;
334     int realD = UP_DIV(c, kC4Align);
335     glTexStorage3D(target, 1, TextrueFormat, realW, realH, realD);
336     OPENGL_CHECK_ERROR;
337   } else if (target == GL_TEXTURE_2D) {
338     MS_ASSERT(w > 0 && h > 0);
339     glGenTextures(1, &textureID);
340     OPENGL_CHECK_ERROR;
341     glBindTexture(target, textureID);
342     OPENGL_CHECK_ERROR;
343     glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
344     OPENGL_CHECK_ERROR;
345     glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
346     OPENGL_CHECK_ERROR;
347     glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
348     OPENGL_CHECK_ERROR;
349     glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
350     OPENGL_CHECK_ERROR;
351     glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
352     OPENGL_CHECK_ERROR;
353 
354     int realW = w * UP_DIV(c, kC4Align);
355     int realH = h;
356     glTexStorage2D(target, 1, TextrueFormat, realW, realH);
357     OPENGL_CHECK_ERROR;
358   }
359 
360   std::vector<int> dims = {w, h, c};
361   std::vector<GLenum> props = {TextrueFormat, target};
362   m_texture_pool_[textureID] = std::make_pair(dims, props);
363 
364   return textureID;
365 }
366 
CopyDeviceTextureToSSBO(GLuint textureID,GLuint ssboBufferID)367 bool OpenGLRuntime::CopyDeviceTextureToSSBO(GLuint textureID, GLuint ssboBufferID) {
368   if (m_texture_pool_.find(textureID) == m_texture_pool_.end()) {
369     return false;
370   }
371   GLuint computeProgram;
372   if (m_texture_pool_[textureID].second[1] == GL_TEXTURE_2D) {
373     computeProgram = OpenGLRuntime::CreateComputeProgram(g_glsl_device_to_host_2d);
374   } else {
375     computeProgram = OpenGLRuntime::CreateComputeProgram(g_glsl_device_to_host_3d);
376   }
377   glUseProgram(computeProgram);
378 
379   // bind the src image texture
380   glBindImageTexture(BIND_INDEX_0, textureID, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32F);
381 
382   // bind the dest output data
383   glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BIND_INDEX_1, ssboBufferID);
384 
385   // set uniform values
386   int width = m_texture_pool_[textureID].first[kWidthIndex];
387   int height = m_texture_pool_[textureID].first[kHeightIndex];
388   int channel = m_texture_pool_[textureID].first[kChannelIndex];
389 
390   glUniform1i(BIND_INDEX_2, width);
391   glUniform1i(BIND_INDEX_3, height);
392   glUniform1i(BIND_INDEX_4, channel);
393 
394   int c_4 = UP_DIV(channel, kC4Align);
395   int gLocalSize[3] = {4, 4, 1};
396   glDispatchCompute(UP_DIV(width, gLocalSize[FIRST_INPUT]), UP_DIV(height, gLocalSize[SECOND_INPUT]),
397                     UP_DIV(c_4, gLocalSize[THIRD_INPUT]));
398 
399   // memory sync
400   glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
401   glDeleteProgram(computeProgram);
402   return true;
403 }
404 
CopyDeviceSSBOToTexture(GLuint ssboBufferID,GLuint textureID)405 bool OpenGLRuntime::CopyDeviceSSBOToTexture(GLuint ssboBufferID, GLuint textureID) {
406   if (m_texture_pool_.find(textureID) == m_texture_pool_.end()) {
407     return false;
408   }
409   GLuint computeProgram;
410   if (m_texture_pool_[textureID].second[1] == GL_TEXTURE_2D) {
411     computeProgram = OpenGLRuntime::CreateComputeProgram(g_glsl_host_to_device_2d);
412   } else {
413     computeProgram = OpenGLRuntime::CreateComputeProgram(g_glsl_host_to_device_3d);
414   }
415   glUseProgram(computeProgram);
416 
417   // bind the src image texture
418   glBindImageTexture(BIND_INDEX_0, textureID, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_RGBA32F);
419 
420   // bind the dest output data
421   glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BIND_INDEX_1, ssboBufferID);
422 
423   // set uniform values
424   int width = m_texture_pool_[textureID].first[kWidthIndex];
425   int height = m_texture_pool_[textureID].first[kHeightIndex];
426   int channel = m_texture_pool_[textureID].first[kChannelIndex];
427 
428   glUniform1i(BIND_INDEX_2, width);
429   glUniform1i(BIND_INDEX_3, height);
430   glUniform1i(BIND_INDEX_4, channel);
431 
432   int c_4 = UP_DIV(channel, kC4Align);
433   int gLocalSize[3] = {4, 4, 1};
434   glDispatchCompute(UP_DIV(width, gLocalSize[FIRST_INPUT]), UP_DIV(height, gLocalSize[SECOND_INPUT]),
435                     UP_DIV(c_4, gLocalSize[THIRD_INPUT]));
436   // memory sync
437   glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
438   glDeleteProgram(computeProgram);
439   return true;
440 }
441 
CopyHostToDeviceTexture(void * hostData,int width,int height,int channel)442 GLuint OpenGLRuntime::CopyHostToDeviceTexture(void *hostData, int width, int height, int channel) {
443   auto ssboBufferID = GLCreateSSBO(sizeof(float) * width * height * channel, hostData);
444   auto textureID = GLCreateTexture(width, height, channel, GL_RGBA32F, GL_TEXTURE_2D);
445   if (textureID == 0) {
446     MS_LOG(ERROR) << "generate GlTexture failed";
447   }
448   CopyDeviceSSBOToTexture(ssboBufferID, textureID);
449   return textureID;
450 }
451 
CopyDeviceTextureToHost(GLuint textureID)452 void *OpenGLRuntime::CopyDeviceTextureToHost(GLuint textureID) {
453   int width = m_texture_pool_[textureID].first[kWidthIndex];
454   int height = m_texture_pool_[textureID].first[kHeightIndex];
455   int channel = m_texture_pool_[textureID].first[kChannelIndex];
456 
457   auto ssboBufferID = GLCreateSSBO(sizeof(float) * width * height * channel);
458   CopyDeviceTextureToSSBO(textureID, ssboBufferID);
459   void *output = malloc(sizeof(float) * width * height * channel);
460   if (output == nullptr) {
461     MS_LOG(ERROR) << "Malloc host data failed";
462     return nullptr;
463   }
464   CopyDeviceSSBOToHost(ssboBufferID, output, sizeof(float) * width * height * channel);
465   return output;
466 }
467 
PrintImage2DData(float * data,int w,int h,int c)468 void OpenGLRuntime::PrintImage2DData(float *data, int w, int h, int c) {
469   for (int i = 0; i < h; i++) {
470     for (int j = 0; j < w; j++) {
471       for (int k = 0; k < c; k++) {
472         std::cout << data[w * c * i + c * j + k] << " ";
473       }
474       std::cout << "    ";
475     }
476   }
477   std::cout << "data print finish!" << std::endl;
478 }
479 #else
480 bool OpenGLRuntime::Init() {
481   MS_LOG(ERROR) << "Init error, server benchmark don't support opengl";
482   return false;
483 }
484 
485 GLuint OpenGLRuntime::GLCreateTexture(int w, int h, int c, GLenum TextrueFormat, GLenum target) { return 0; }
486 void *OpenGLRuntime::CopyDeviceTextureToHost(GLuint textureID) { return nullptr; }
487 GLuint OpenGLRuntime::CopyHostToDeviceTexture(void *hostData, int width, int height, int channel) { return 0; }
488 
489 void OpenGLRuntime::PrintImage2DData(float *data, int w, int h, int c) {}
490 #endif
491 }  // namespace OpenGL
492 }  // namespace mindspore
493