pyrender离屏渲染eglInitialize失败

在跑项目代码的时候需要使用pyrender进行离屏渲染,遇到了这个问题
在这里插入图片描述

网上的说法一般都是让不用egl,换成mesa使用cpu进行渲染,但是安装mesa也极其麻烦,安装llvm依赖需要make好几个小时,而且很容易安装失败(我研究了一下午也没安成功)。所以想探究一下为什么为eglInitialize失败

省流:如何修改代码可以跑通:

  • pyrender/platforms/egl.py文件中get_device_by_index函数return device[0]改为devices[8]
  • class EGLDevice.name中return None改为return ‘/dev/dri/card0’。
  if name is None:
       return '/dev/dri/card0'
       # return None

研究过程

报错的代码为assert eglInitialize(self._egl_display, major, minor),major和minor都是个int常数,并且上面报错有个EGLdisplay_pointer,所以猜想问题出在display也就是渲染设备这里。
众所周知linux以文件的形式管理输入输出设备,显卡设备在/dev/dri目录下:
在这里插入图片描述

通过阅读代码发现,egl在渲染时,需要先选择进行渲染的设备,代码在pyrender/platforms/egl.py之中。我使用的机器为8卡机器。
选择的逻辑是先看当前设备有几张卡,即/dev/dri下面card的数量,然后将所有的设备转为egl自己定义的设备格式,然后在默认状态下选择card0进行渲染。
这里由于代码是直接从/dev/dri目录下读取设备,所以如果运行的时候设置了export CUDA_VISIBLE_DEVICES=0,也不能将多卡机器模拟成单卡从而避免这个bug。
但是bug的问题在于,由于未知原因,设备转为egl自己定义的设备格式并返回设备列表时,卡的顺序会反转,所以最后返回的列表长这样
在这里插入图片描述

而由于代码默认使用device[0],所以最后执行渲染任务的是card8。于是在这里猜测是否由于GPU编号0-7和1-8冲突了,所以没有card8,也就没法渲染。于是在这里换成使用device[1],即card7进行渲染,但是依然不行
然后突然想到为什么机器是8张卡,/dev/dri目录下却有9张卡(card0~card9),所以猜测可能card0是用作指令传输的主卡,想尝试使用card0进行渲染试一下。
但是上面的列表中最后一项为<EGLDevice(name=None)>,并没有card0,上代码里看到是这样的
在这里插入图片描述

这里可能是因为某种神奇原因(可能是把0当成False了),所以name返回的是None。于是手动把if name is None让它返回'/dev/dri/card0',并把上面device[0]改为devices[8],这样就可以使用card0进行渲染。
验证运行成功

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值