visionipc: remove OpenCL support (#673)

* visionipc: remove OpenCL support

* less cl
This commit is contained in:
Adeeb Shihadeh
2026-02-06 16:32:26 -08:00
committed by GitHub
parent 20f2493855
commit f9ebdca885
13 changed files with 93 additions and 197 deletions

View File

@@ -18,31 +18,25 @@ msgq = env.Library('msgq', msgq_objects)
msgq_python = envCython.Program('msgq/ipc_pyx.so', 'msgq/ipc_pyx.pyx', LIBS=envCython["LIBS"]+[msgq, "zmq", common])
# Build Vision IPC
vipc_files = ['visionipc.cc', 'visionipc_server.cc', 'visionipc_client.cc', 'visionbuf.cc']
vipc_sources = [f'{visionipc_dir.abspath}/{f}' for f in vipc_files]
vipc_files = ['visionipc.cc', 'visionipc_server.cc', 'visionipc_client.cc']
if arch == "larch64":
vipc_sources += [f'{visionipc_dir.abspath}/visionbuf_ion.cc']
vipc_files += ['visionbuf_ion.cc']
else:
vipc_sources += [f'{visionipc_dir.abspath}/visionbuf_cl.cc']
vipc_files += ['visionbuf.cc']
vipc_sources = [f'{visionipc_dir.abspath}/{f}' for f in vipc_files]
vipc_objects = env.SharedObject(vipc_sources)
visionipc = env.Library('visionipc', vipc_objects)
vipc_frameworks = []
vipc_libs = envCython["LIBS"] + [visionipc, msgq, common, "zmq"]
if arch == "Darwin":
vipc_frameworks.append('OpenCL')
else:
vipc_libs.append('OpenCL')
envCython.Program(f'{visionipc_dir.abspath}/visionipc_pyx.so', f'{visionipc_dir.abspath}/visionipc_pyx.pyx',
LIBS=vipc_libs, FRAMEWORKS=vipc_frameworks)
LIBS=vipc_libs)
if GetOption('extras'):
env.Program('msgq/test_runner', ['msgq/test_runner.cc', 'msgq/msgq_tests.cc'], LIBS=[msgq, common])
env.Program(f'{visionipc_dir.abspath}/test_runner',
[f'{visionipc_dir.abspath}/test_runner.cc', f'{visionipc_dir.abspath}/visionipc_tests.cc'],
LIBS=['pthread'] + vipc_libs, FRAMEWORKS=vipc_frameworks)
LIBS=['pthread'] + vipc_libs)
Export('visionipc', 'msgq', 'msgq_python')

View File

@@ -1,5 +1,52 @@
#include "msgq/visionipc/visionbuf.h"
#include <atomic>
#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
std::atomic<int> offset = 0;
static void *malloc_with_fd(size_t len, int *fd) {
char full_path[0x100];
#ifdef __APPLE__
snprintf(full_path, sizeof(full_path)-1, "/tmp/visionbuf_%d_%d", getpid(), offset++);
#else
snprintf(full_path, sizeof(full_path)-1, "/dev/shm/msgq_visionbuf_%d_%d", getpid(), offset++);
#endif
*fd = open(full_path, O_RDWR | O_CREAT, 0664);
assert(*fd >= 0);
unlink(full_path);
ftruncate(*fd, len);
void *addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
assert(addr != MAP_FAILED);
return addr;
}
void VisionBuf::allocate(size_t length) {
this->len = length;
this->mmap_len = this->len + sizeof(uint64_t);
this->addr = malloc_with_fd(this->mmap_len, &this->fd);
this->frame_id = (uint64_t*)((uint8_t*)this->addr + this->len);
}
void VisionBuf::import(){
assert(this->fd >= 0);
this->addr = mmap(NULL, this->mmap_len, PROT_READ | PROT_WRITE, MAP_SHARED, this->fd, 0);
assert(this->addr != MAP_FAILED);
this->frame_id = (uint64_t*)((uint8_t*)this->addr + this->len);
}
void VisionBuf::init_yuv(size_t init_width, size_t init_height, size_t init_stride, size_t init_uv_offset){
this->width = init_width;
this->height = init_height;
@@ -10,6 +57,17 @@ void VisionBuf::init_yuv(size_t init_width, size_t init_height, size_t init_stri
this->uv = this->y + this->uv_offset;
}
int VisionBuf::sync(int dir) {
return 0;
}
int VisionBuf::free() {
int err = munmap(this->addr, this->mmap_len);
if (err != 0) return err;
err = close(this->fd);
return err;
}
uint64_t VisionBuf::get_frame_id() {
return *frame_id;

View File

@@ -2,13 +2,6 @@
#include "msgq/visionipc/visionipc.h"
#define CL_USE_DEPRECATED_OPENCL_1_2_APIS
#ifdef __APPLE__
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#endif
#define VISIONBUF_SYNC_FROM_DEVICE 0
#define VISIONBUF_SYNC_TO_DEVICE 1
@@ -43,16 +36,11 @@ class VisionBuf {
size_t idx = 0;
VisionStreamType type;
// OpenCL
cl_mem buf_cl = nullptr;
cl_command_queue copy_q = nullptr;
// ion
int handle = 0;
void allocate(size_t len);
void import();
void init_cl(cl_device_id device_id, cl_context ctx);
void init_yuv(size_t width, size_t height, size_t stride, size_t uv_offset);
int sync(int dir);
int free();

View File

@@ -1,94 +0,0 @@
#include "msgq/visionipc/visionbuf.h"
#include <atomic>
#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
std::atomic<int> offset = 0;
static void *malloc_with_fd(size_t len, int *fd) {
char full_path[0x100];
#ifdef __APPLE__
snprintf(full_path, sizeof(full_path)-1, "/tmp/visionbuf_%d_%d", getpid(), offset++);
#else
snprintf(full_path, sizeof(full_path)-1, "/dev/shm/msgq_visionbuf_%d_%d", getpid(), offset++);
#endif
*fd = open(full_path, O_RDWR | O_CREAT, 0664);
assert(*fd >= 0);
unlink(full_path);
ftruncate(*fd, len);
void *addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
assert(addr != MAP_FAILED);
return addr;
}
void VisionBuf::allocate(size_t length) {
this->len = length;
this->mmap_len = this->len + sizeof(uint64_t);
this->addr = malloc_with_fd(this->mmap_len, &this->fd);
this->frame_id = (uint64_t*)((uint8_t*)this->addr + this->len);
}
void VisionBuf::init_cl(cl_device_id device_id, cl_context ctx){
int err;
this->copy_q = clCreateCommandQueue(ctx, device_id, 0, &err);
assert(err == 0);
this->buf_cl = clCreateBuffer(ctx, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, this->len, this->addr, &err);
assert(err == 0);
}
void VisionBuf::import(){
assert(this->fd >= 0);
this->addr = mmap(NULL, this->mmap_len, PROT_READ | PROT_WRITE, MAP_SHARED, this->fd, 0);
assert(this->addr != MAP_FAILED);
this->frame_id = (uint64_t*)((uint8_t*)this->addr + this->len);
}
int VisionBuf::sync(int dir) {
int err = 0;
if (!this->buf_cl) return 0;
if (dir == VISIONBUF_SYNC_FROM_DEVICE) {
err = clEnqueueReadBuffer(this->copy_q, this->buf_cl, CL_FALSE, 0, this->len, this->addr, 0, NULL, NULL);
} else {
err = clEnqueueWriteBuffer(this->copy_q, this->buf_cl, CL_FALSE, 0, this->len, this->addr, 0, NULL, NULL);
}
if (err == 0){
err = clFinish(this->copy_q);
}
return err;
}
int VisionBuf::free() {
int err = 0;
if (this->buf_cl){
err = clReleaseMemObject(this->buf_cl);
if (err != 0) return err;
err = clReleaseCommandQueue(this->copy_q);
if (err != 0) return err;
}
err = munmap(this->addr, this->mmap_len);
if (err != 0) return err;
err = close(this->fd);
return err;
}

View File

@@ -10,7 +10,6 @@
#include <fcntl.h>
#include <unistd.h>
#include <linux/ion.h>
#include <CL/cl_ext.h>
#include <msm_ion.h>
@@ -27,19 +26,6 @@
ret; \
})
// just hard-code these for convenience
// size_t device_page_size = 0;
// clGetDeviceInfo(device_id, CL_DEVICE_PAGE_SIZE_QCOM,
// sizeof(device_page_size), &device_page_size,
// NULL);
// size_t padding_cl = 0;
// clGetDeviceInfo(device_id, CL_DEVICE_EXT_MEM_PADDING_IN_BYTES_QCOM,
// sizeof(padding_cl), &padding_cl,
// NULL);
#define DEVICE_PAGE_SIZE_CL 4096
#define PADDING_CL 0
struct IonFileHandle {
IonFileHandle() {
fd = open("/dev/ion", O_RDWR | O_NONBLOCK);
@@ -58,7 +44,7 @@ int ion_fd() {
void VisionBuf::allocate(size_t length) {
struct ion_allocation_data ion_alloc = {0};
ion_alloc.len = length + PADDING_CL + sizeof(uint64_t);
ion_alloc.len = length + sizeof(uint64_t);
ion_alloc.align = 4096;
ion_alloc.heap_id_mask = 1 << ION_IOMMU_HEAP_ID;
ion_alloc.flags = ION_FLAG_CACHED;
@@ -83,7 +69,7 @@ void VisionBuf::allocate(size_t length) {
this->addr = mmap_addr;
this->handle = ion_alloc.handle;
this->fd = ion_fd_data.fd;
this->frame_id = (uint64_t*)((uint8_t*)this->addr + this->len + PADDING_CL);
this->frame_id = (uint64_t*)((uint8_t*)this->addr + this->len);
}
void VisionBuf::import(){
@@ -100,27 +86,19 @@ void VisionBuf::import(){
this->addr = mmap(NULL, this->mmap_len, PROT_READ | PROT_WRITE, MAP_SHARED, this->fd, 0);
assert(this->addr != MAP_FAILED);
this->frame_id = (uint64_t*)((uint8_t*)this->addr + this->len + PADDING_CL);
this->frame_id = (uint64_t*)((uint8_t*)this->addr + this->len);
}
void VisionBuf::init_cl(cl_device_id device_id, cl_context ctx) {
int err;
void VisionBuf::init_yuv(size_t init_width, size_t init_height, size_t init_stride, size_t init_uv_offset){
this->width = init_width;
this->height = init_height;
this->stride = init_stride;
this->uv_offset = init_uv_offset;
assert(((uintptr_t)this->addr % DEVICE_PAGE_SIZE_CL) == 0);
cl_mem_ion_host_ptr ion_cl = {0};
ion_cl.ext_host_ptr.allocation_type = CL_MEM_ION_HOST_PTR_QCOM;
ion_cl.ext_host_ptr.host_cache_policy = CL_MEM_HOST_UNCACHED_QCOM;
ion_cl.ion_filedesc = this->fd;
ion_cl.ion_hostptr = this->addr;
this->buf_cl = clCreateBuffer(ctx,
CL_MEM_USE_HOST_PTR | CL_MEM_EXT_HOST_PTR_QCOM,
this->len, &ion_cl, &err);
assert(err == 0);
this->y = (uint8_t *)this->addr;
this->uv = this->y + this->uv_offset;
}
int VisionBuf::sync(int dir) {
struct ion_flush_data flush_data = {0};
flush_data.handle = this->handle;
@@ -143,14 +121,7 @@ int VisionBuf::sync(int dir) {
}
int VisionBuf::free() {
int err = 0;
if (this->buf_cl){
err = clReleaseMemObject(this->buf_cl);
if (err != 0) return err;
}
err = munmap(this->addr, this->mmap_len);
int err = munmap(this->addr, this->mmap_len);
if (err != 0) return err;
err = close(this->fd);
@@ -159,3 +130,11 @@ int VisionBuf::free() {
struct ion_handle_data handle_data = {.handle = this->handle};
return HANDLE_EINTR(ioctl(ion_fd(), ION_IOC_FREE, &handle_data));
}
uint64_t VisionBuf::get_frame_id() {
return *frame_id;
}
void VisionBuf::set_frame_id(uint64_t id) {
*frame_id = id;
}

View File

@@ -8,14 +8,6 @@ from libc.stdint cimport uint32_t, uint64_t
from libcpp cimport bool, int
cdef extern from "msgq/visionipc/visionbuf.h":
struct _cl_device_id
struct _cl_context
struct _cl_mem
ctypedef _cl_device_id * cl_device_id
ctypedef _cl_context * cl_context
ctypedef _cl_mem * cl_mem
cdef enum VisionStreamType:
pass
@@ -28,7 +20,6 @@ cdef extern from "msgq/visionipc/visionbuf.h":
size_t stride
size_t uv_offset
size_t idx
cl_mem buf_cl
void set_frame_id(uint64_t id)
cdef extern from "msgq/visionipc/visionipc.h":
@@ -42,7 +33,7 @@ cdef extern from "msgq/visionipc/visionipc_server.h":
string get_endpoint_name(string, VisionStreamType)
cdef cppclass VisionIpcServer:
VisionIpcServer(string, void*, void*)
VisionIpcServer(string)
void create_buffers(VisionStreamType, size_t, size_t, size_t)
void create_buffers_with_sizes(VisionStreamType, size_t, size_t, size_t, size_t, size_t, size_t)
VisionBuf * get_buffer(VisionStreamType)
@@ -53,7 +44,7 @@ cdef extern from "msgq/visionipc/visionipc_client.h":
cdef cppclass VisionIpcClient:
int num_buffers
VisionBuf buffers[1]
VisionIpcClient(string, VisionStreamType, bool, void*, void*)
VisionIpcClient(string, VisionStreamType, bool)
VisionBuf * recv(VisionIpcBufExtra *, int)
bool connect(bool)
bool is_connected()

View File

@@ -22,7 +22,7 @@ static int connect_to_vipc_server(const std::string &name, bool blocking) {
return socket_fd;
}
VisionIpcClient::VisionIpcClient(std::string name, VisionStreamType type, bool conflate, cl_device_id device_id, cl_context ctx) : name(name), type(type), device_id(device_id), ctx(ctx) {
VisionIpcClient::VisionIpcClient(std::string name, VisionStreamType type, bool conflate) : name(name), type(type) {
msg_ctx = Context::create();
sock = SubSocket::create(msg_ctx, get_endpoint_name(name, type), "127.0.0.1", conflate, false);
@@ -71,8 +71,6 @@ bool VisionIpcClient::connect(bool blocking) {
buffers[i].fd = fds[i];
buffers[i].import();
buffers[i].init_yuv(buffers[i].width, buffers[i].height, buffers[i].stride, buffers[i].uv_offset);
if (device_id) buffers[i].init_cl(device_id, ctx);
}
close(socket_fd);

View File

@@ -14,15 +14,12 @@ private:
SubSocket * sock;
Poller * poller;
cl_device_id device_id = nullptr;
cl_context ctx = nullptr;
public:
bool connected = false;
VisionStreamType type;
int num_buffers = 0;
VisionBuf buffers[VISIONIPC_MAX_FDS];
VisionIpcClient(std::string name, VisionStreamType type, bool conflate, cl_device_id device_id=nullptr, cl_context ctx=nullptr);
VisionIpcClient(std::string name, VisionStreamType type, bool conflate);
~VisionIpcClient();
VisionBuf * recv(VisionIpcBufExtra * extra=nullptr, const int timeout_ms=100);
bool connect(bool blocking=true);

View File

@@ -2,11 +2,6 @@
#cython: language_level=3
from .visionipc cimport VisionBuf as cppVisionBuf
from .visionipc cimport cl_device_id, cl_context
cdef class CLContext:
cdef cl_device_id device_id
cdef cl_context context
cdef class VisionBuf:
cdef cppVisionBuf * buf

View File

@@ -68,7 +68,7 @@ cdef class VisionIpcServer:
cdef cppVisionIpcServer * server
def __init__(self, string name):
self.server = new cppVisionIpcServer(name, NULL, NULL)
self.server = new cppVisionIpcServer(name)
def create_buffers(self, VisionStreamType tp, size_t num_buffers, size_t width, size_t height):
self.server.create_buffers(tp, num_buffers, width, height)
@@ -102,11 +102,8 @@ cdef class VisionIpcClient:
cdef cppVisionIpcClient * client
cdef VisionIpcBufExtra extra
def __cinit__(self, string name, VisionStreamType stream, bool conflate, CLContext context = None):
if context:
self.client = new cppVisionIpcClient(name, stream, conflate, context.device_id, context.context)
else:
self.client = new cppVisionIpcClient(name, stream, conflate, NULL, NULL)
def __cinit__(self, string name, VisionStreamType stream, bool conflate):
self.client = new cppVisionIpcClient(name, stream, conflate)
def __dealloc__(self):
del self.client

View File

@@ -32,7 +32,7 @@ std::string get_ipc_path(const std::string& name) {
return path + "visionipc_" + name;
}
VisionIpcServer::VisionIpcServer(std::string name, cl_device_id device_id, cl_context ctx) : name(name), device_id(device_id), ctx(ctx) {
VisionIpcServer::VisionIpcServer(std::string name) : name(name) {
msg_ctx = Context::create();
std::random_device rd("/dev/urandom");
@@ -63,8 +63,6 @@ void VisionIpcServer::create_buffers_with_sizes(VisionStreamType type, size_t nu
buf->idx = i;
buf->type = type;
if (device_id) buf->init_cl(device_id, ctx);
buf->init_yuv(width, height, stride, uv_offset);
buffers[type].push_back(buf);
@@ -142,9 +140,7 @@ void VisionIpcServer::listener(){
fds[i] = buffers[type][i]->fd;
bufs[i] = *buffers[type][i];
// Remove some private openCL/ion metadata
bufs[i].buf_cl = 0;
bufs[i].copy_q = 0;
// Remove some private ion metadata
bufs[i].handle = 0;
bufs[i].server_id = server_id;

View File

@@ -13,8 +13,6 @@ std::string get_ipc_path(const std::string &name);
class VisionIpcServer {
private:
cl_device_id device_id = nullptr;
cl_context ctx = nullptr;
uint64_t server_id;
std::atomic<bool> should_exit = false;
@@ -30,7 +28,7 @@ class VisionIpcServer {
void listener(void);
public:
VisionIpcServer(std::string name, cl_device_id device_id=nullptr, cl_context ctx=nullptr);
VisionIpcServer(std::string name);
~VisionIpcServer();
VisionBuf * get_buffer(VisionStreamType type, int idx = -1);

View File

@@ -21,7 +21,6 @@ elif [[ $PLATFORM == "Linux" ]]; then
sudo apt-get install -y --no-install-recommends \
curl ca-certificates \
libzmq3-dev \
ocl-icd-opencl-dev opencl-headers \
python3-dev python3-pip python3-venv
else
echo "WARNING: unsupported platform. skipping apt/brew install."