MNN适配POCL
# MNN适配POCL完整流程指南
## 一、MNN适配POCL的意义
### 1.1 技术价值
**扩展硬件支持范围**
- MNN原本主要针对GPU设备(如Adreno、Mali等)进行OpenCL优化
- PoCL(Portable Computing Language)提供CPU上的OpenCL实现
- 适配后MNN可以在没有GPU的CPU服务器上运行OpenCL后端
**统一计算框架**
- 使用相同的OpenCL API,无需修改上层应用代码
- 在CPU和GPU之间保持一致的编程模型
- 便于在不同硬件平台间迁移和部署
**性能优化潜力**
- PoCL利用CPU的SIMD指令(AVX、SSE等)加速计算
- 支持多核并行计算,充分利用多核CPU资源
- 对于某些计算密集型任务,CPU OpenCL可能比传统CPU后端更高效
### 1.2 应用场景
- **无GPU服务器**:在没有GPU的云服务器上运行深度学习推理
- **开发测试**:在本地开发环境中快速验证OpenCL代码逻辑
- **混合部署**:在CPU和GPU混合环境中统一使用OpenCL后端
- **边缘计算**:在资源受限的边缘设备上利用CPU进行推理
### 1.3 严格模式的意义
通过环境变量`MNN_STRICT_OPENCL_NO_CPU_OP`启用严格模式后:
- 禁止操作级别的CPU回退,确保所有计算都在OpenCL上执行
- 验证OpenCL后端的完整性,发现不支持的算子
- 避免静默的CPU回退导致的性能下降
- 提供明确的错误信息,便于调试和优化
---
## 二、代码修改详解
### 2.1 核心修改文件
基于git提交记录,主要修改了以下文件:
1. `source/backend/opencl/core/OpenCLBackend.cpp`
2. `source/backend/opencl/core/runtime/OpenCLRuntime.cpp`
3. `source/core/Backend.cpp`
4. `source/core/Pipeline.cpp`
### 2.2 OpenCLRuntime设备检测修改
**文件**:`source/backend/opencl/core/runtime/OpenCLRuntime.cpp`
**问题**:原代码只查找GPU设备,PoCL提供的是CPU设备,导致无法找到设备。
**修改前**:
```cpp
res = platforms[platformId].getDevices(CL_DEVICE_TYPE_GPU, &gpuDevices);
if(1 <= gpuDevices.size() && res == CL_SUCCESS) {
// ... 使用GPU设备
}
修改后:
// Prefer GPU devices, but for PoCL (CPU OpenCL) we may have only CPU devices.
res = platforms[platformId].getDevices(CL_DEVICE_TYPE_GPU, &gpuDevices);
if ((res != CL_SUCCESS || gpuDevices.empty())) {
std::vector<cl::Device> allDevices;
cl_int res2 = platforms[platformId].getDevices(CL_DEVICE_TYPE_ALL, &allDevices);
MNN_CHECK_CL_SUCCESS(res2, "getDevices(ALL)");
if (res2 == CL_SUCCESS && !allDevices.empty()) {
gpuDevices = std::move(allDevices);
res = CL_SUCCESS;
}
}
说明:当GPU设备查找失败时,回退到查找所有类型的设备(包括CPU设备),从而支持PoCL的CPU设备。
2.3 OpenCLBackend运行时创建日志增强
文件:source/backend/opencl/core/OpenCLBackend.cpp
修改前:
mOpenCLRuntime.reset(new OpenCLRuntime(platform_size, platform_id, device_id, context_ptr, hint()));
//Whether runtimeError
mCLRuntimeError = mOpenCLRuntime->isCreateError();
修改后:
mOpenCLRuntime.reset(new OpenCLRuntime(platform_size, platform_id, device_id, context_ptr, hint()));
// Whether runtimeError
mCLRuntimeError = mOpenCLRuntime->isCreateError();
if (mCLRuntimeError) {
MNN_PRINT("[MNN][OpenCL] OpenCLRuntime create error (platform_size=%d platform_id=%d device_id=%d context_ptr=%p)\n",
platform_size, platform_id, device_id, context_ptr);
} else {
MNN_PRINT("[MNN][OpenCL] OpenCLRuntime created (platform_size=%d platform_id=%d device_id=%d context_ptr=%p)\n",
platform_size, platform_id, device_id, context_ptr);
}
说明:添加详细的日志输出,便于调试OpenCL运行时创建过程。
2.4 RuntimeCreator验证日志增强
文件:source/backend/opencl/core/OpenCLBackend.cpp
修改前:
auto rt = new CLRuntime(info);
if(rt->isCLRuntimeError() == true) {
delete rt;
return nullptr;
}
return rt;
修改后:
auto rt = new CLRuntime(info);
if(rt->isCLRuntimeError() == true) {
MNN_PRINT("[MNN][OpenCL] CLRuntime creation failed (isCLRuntimeError=1).\n");
delete rt;
return nullptr;
}
MNN_PRINT("[MNN][OpenCL] CLRuntime creation OK.\n");
return rt;
2.5 Backend运行时创建严格模式
文件:source/core/Backend.cpp
新增代码:
// Optional strict mode: disallow creating CPU runtime/creator when running OpenCL-only.
// This is used to ensure actual computation doesn't silently fall back to CPU.
// Allowed host-side tensor copies may still happen outside runtime creation.
static int sStrictNoCpu = -1;
if (sStrictNoCpu < 0) {
const char* v = ::getenv("MNN_STRICT_NO_CPU_RUNTIME");
sStrictNoCpu = (v && v[0] && v[0] != '0') ? 1 : 0;
}
if (sStrictNoCpu == 1 && type == MNN_FORWARD_CPU) {
MNN_PRINT("[MNN][STRICT] CPU runtime creation is disabled (MNN_STRICT_NO_CPU_RUNTIME=1).\n");
return nullptr;
}
说明:通过环境变量MNN_STRICT_NO_CPU_RUNTIME控制是否禁用CPU运行时创建。
新增日志:
auto iter = gExtraCreator.find(type);
if (iter == gExtraCreator.end()) {
MNN_PRINT("[MNN] RuntimeCreator not found for type=%d\n", (int)type);
return nullptr;
}
// needCheck == false
if (!iter->second.second) {
MNN_PRINT("[MNN] RuntimeCreator found for type=%d (needCheck=0)\n", (int)type);
return iter->second.first;
}
Backend::Info info;
info.type = type;
std::shared_ptr<Runtime> bn(iter->second.first->onCreate(info));
if (nullptr != bn.get()) {
MNN_PRINT("[MNN] RuntimeCreator validated for type=%d (onCreate ok)\n", (int)type);
return iter->second.first;
}
MNN_PRINT("[MNN] RuntimeCreator present but validation failed for type=%d (onCreate returned null)\n", (int)type);
return nullptr;
2.6 Pipeline严格模式:禁止CPU回退
文件:source/core/Pipeline.cpp
新增代码1:禁止操作级别的CPU回退
if (nullptr == iter.execution) {
// Try Backup
static int sStrictNoCpuOp = -1;
if (sStrictNoCpuOp < 0) {
const char* v = ::getenv("MNN_STRICT_OPENCL_NO_CPU_OP");
sStrictNoCpuOp = (v && v[0] && v[0] != '0') ? 1 : 0;
}
if (sStrictNoCpuOp == 1) {
// Do not allow fallback to backup backend for ops. This keeps compute ops on OpenCL.
if (mInfo.first.reportError) {
const char* opname = (iter.op && iter.op->name()) ? iter.op->name()->c_str() : "";
MNN_ERROR("[MNN][STRICT] OpenCL has no execution for op type=%d name=%s; CPU fallback disabled\n", iter.op->type(), opname);
}
return NOT_SUPPORT;
}
iter.execution.reset(OpCommonUtils::createExecutionWithExternal(mBackupBackend.get(), iter.inputs, iter.outputs, iter.op, &loader, tmpStorage));
// ...
}
新增代码2:验证操作确实在OpenCL上执行
// Strict mode: ensure compute ops are executed on OpenCL backend (no CPU fallback).
static int sStrictNoCpuOp2 = -1;
if (sStrictNoCpuOp2 < 0) {
const char* v = ::getenv("MNN_STRICT_OPENCL_NO_CPU_OP");
sStrictNoCpuOp2 = (v && v[0] && v[0] != '0') ? 1 : 0;
}
if (sStrictNoCpuOp2 == 1) {
auto b = iter.execution->backend();
if (b && b->type() != MNN_FORWARD_OPENCL) {
const char* opname = (iter.op && iter.op->name()) ? iter.op->name()->c_str() : "";
MNN_ERROR("[MNN][STRICT] Op execution is not OpenCL (backend=%d) for op type=%d name=%s\n",
(int)b->type(), (int)iter.op->type(), opname);
return NOT_SUPPORT;
}
}
说明:通过环境变量MNN_STRICT_OPENCL_NO_CPU_OP控制是否启用严格模式,确保所有计算操作都在OpenCL后端执行。
三、编译配置
3.1 环境准备
系统要求:
- GCC 12+ 编译器
- CMake 3.10+
- Ninja构建工具
依赖安装:
# 安装基础编译工具
sudo yum install -y gcc gcc-c++ cmake ninja-build git
# 安装POCL和OpenCL ICD加载器
sudo yum install -y pocl pocl-devel ocl-icd ocl-icd-devel
# 验证POCL安装
clinfo
3.2 编译脚本
文件:pocl_test/build_opencl_pocl.sh
#!/usr/bin/env bash
set -euo pipefail
# Build MNN with OpenCL enabled, build PoCL validation demos, and run them.
#
# Expected environment:
# - OpenCL ICD loader installed
# - PoCL installed and registered via /etc/OpenCL/vendors/pocl.icd (system ICD)
#
# Optional strict validation (enabled by patch in this branch):
# export MNN_STRICT_NO_CPU_RUNTIME=1
# export MNN_STRICT_OPENCL_NO_CPU_OP=1
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BUILD_DIR="${ROOT_DIR}/build_pocl_opencl"
mkdir -p "${BUILD_DIR}"
cd "${BUILD_DIR}"
cmake "${ROOT_DIR}" \
-GNinja \
-DMNN_OPENCL=ON \
-DMNN_BUILD_SHARED_LIBS=ON \
-DMNN_BUILD_TOOLS=ON \
-DMNN_BUILD_CONVERTER=OFF \
-DMNN_BUILD_DEMO=OFF \
-DMNN_BUILD_POCL_TEST=ON
ninja -j"$(nproc)" MNN MNN_CL pocl_smoke run_mnn_opencl run_mnn_opencl_model
export LD_LIBRARY_PATH="${BUILD_DIR}/source/backend/opencl:${BUILD_DIR}:${LD_LIBRARY_PATH:-}"
echo "\n[Run] pocl_smoke"
"${BUILD_DIR}/pocl_test/pocl_smoke" || true
echo "\n[Run] run_mnn_opencl_model"
if [[ -f "${ROOT_DIR}/tiny_matmul_add.mnn" ]]; then
"${BUILD_DIR}/pocl_test/run_mnn_opencl_model" "${ROOT_DIR}/tiny_matmul_add.mnn" || true
else
echo "Missing ${ROOT_DIR}/tiny_matmul_add.mnn (optional). See pocl_test/README.md to generate it."
fi
3.3 CMake配置说明
关键参数:
-DMNN_OPENCL=ON:启用OpenCL后端-DMNN_BUILD_SHARED_LIBS=ON:构建共享库libMNN.so-DMNN_BUILD_TOOLS=ON:构建工具-DMNN_BUILD_POCL_TEST=ON:构建POCL测试程序-GNinja:使用Ninja构建系统
3.4 编译步骤
# 1. 进入MNN源码目录
cd /root/workspace/mnn
# 2. 执行编译脚本
bash pocl_test/build_opencl_pocl.sh
# 3. 编译产物
# - libMNN.so:MNN主库
# - libMNN_CL.so:OpenCL后端插件
# - pocl_smoke:OpenCL烟雾测试程序
# - run_mnn_opencl_model:MNN模型测试程序
四、模型转换
4.1 模型概述
测试模型:tiny_matmul_add
模型结构:Y = X @ W + B
- 输入:X [M, K]
- 权重:W [K, N]
- 偏置:B [N]
- 输出:Y [M, N]
默认形状:M=1, K=2, N=3
- X: [1, 2]
- W: [2, 3]
- B: [3]
- Y: [1, 3]
4.2 生成ONNX模型
方法1:使用Python脚本生成
文件:pocl_test/gen_tiny_matmul_add_onnx.py
依赖安装:
pip install onnx numpy
生成命令:
cd /root/workspace/mnn/pocl_test
python3 gen_tiny_matmul_add_onnx.py --out tiny_matmul_add.onnx
自定义形状:
python3 gen_tiny_matmul_add_onnx.py --out tiny_matmul_add.onnx --m 2 --k 4 --n 6
脚本内容:
#!/usr/bin/env python3
"""Generate a tiny ONNX model: Y = X @ W + B
This is used to create a minimal, reproducible test model for validating MNN OpenCL execution on PoCL.
Outputs:
- tiny_matmul_add.onnx (by default in repo root)
Requirements:
- onnx
- numpy
Install example:
pip install onnx numpy
"""
import argparse
import numpy as np
import onnx
from onnx import helper, TensorProto, numpy_helper
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--out", default="tiny_matmul_add.onnx", help="Output ONNX file")
ap.add_argument("--m", type=int, default=1)
ap.add_argument("--k", type=int, default=2)
ap.add_argument("--n", type=int, default=3)
args = ap.parse_args()
# Shapes
# X: [M, K]
# W: [K, N]
# B: [N] (broadcast to [M, N])
M, K, N = args.m, args.k, args.n
X = helper.make_tensor_value_info("X", TensorProto.FLOAT, [M, K])
Y = helper.make_tensor_value_info("Y", TensorProto.FLOAT, [M, N])
# Deterministic weights/bias for easy checking
W_np = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], dtype=np.float32)
if W_np.shape != (K, N):
# generate sequential values if user picks different K/N
W_np = np.arange(K * N, dtype=np.float32).reshape(K, N) + 1.0
B_np = np.array([0.5, -0.25, 1.0], dtype=np.float32)
if B_np.shape != (N,):
B_np = (np.arange(N, dtype=np.float32) * 0.1).astype(np.float32)
W = numpy_helper.from_array(W_np, name="W")
B = numpy_helper.from_array(B_np, name="B")
matmul = helper.make_node("MatMul", ["X", "W"], ["Z"], name="matmul")
add = helper.make_node("Add", ["Z", "B"], ["Y"], name="add")
graph = helper.make_graph(
nodes=[matmul, add],
name="tiny_matmul_add",
inputs=[X],
outputs=[Y],
initializer=[W, B],
)
model = helper.make_model(graph, producer_name="mnn_pocl_test")
onnx.checker.check_model(model)
onnx.save(model, args.out)
print(f"Wrote {args.out} (X:[{M},{K}] W:[{K},{N}] B:[{N}] -> Y:[{M},{N}])")
if __name__ == "__main__":
main()
4.3 转换为MNN格式
前提条件:需要编译MNNConvert工具
编译MNNConvert:
cd /root/workspace/mnn
mkdir build_conv && cd build_conv
cmake .. -DMNN_BUILD_CONVERTER=ON
make -j$(nproc) MNNConvert
转换命令:
./build_conv/MNNConvert -f ONNX --modelFile tiny_matmul_add.onnx --MNNModel tiny_matmul_add.mnn --bizCode MNN
参数说明:
-f ONNX:指定输入模型格式为ONNX--modelFile tiny_matmul_add.onnx:输入ONNX模型文件路径--MNNModel tiny_matmul_add.mnn:输出MNN模型文件路径--bizCode MNN:MNN模型标识
完整流程:
# 1. 生成ONNX模型
cd /root/workspace/mnn/pocl_test
python3 gen_tiny_matmul_add_onnx.py --out ../tiny_matmul_add.onnx
# 2. 转换为MNN格式
cd /root/workspace/mnn
./build_conv/MNNConvert -f ONNX --modelFile tiny_matmul_add.onnx --MNNModel tiny_matmul_add.mnn --bizCode MNN
# 3. 验证模型文件
ls -lh tiny_matmul_add.mnn
4.4 模型验证
预期输出(默认形状 M=1, K=2, N=3):
输入 X = [[1, 2]]
权重 W = [[1, 2, 3], [4, 5, 6]]
偏置 B = [0.5, -0.25, 1.0]
计算过程:
Z = X @ W = [1, 2] @ [[1, 2, 3], [4, 5, 6]]
= [1*1 + 2*4, 1*2 + 2*5, 1*3 + 2*6]
= [9, 12, 15]
Y = Z + B = [9, 12, 15] + [0.5, -0.25, 1.0]
= [9.5, 11.75, 16.0]
MNN推理输出:
y=[9.5,11.75,16]
五、测试验证
5.1 测试程序说明
测试目录结构:
pocl_test/
├── CMakeLists.txt # 测试程序构建配置
├── build_opencl_pocl.sh # 编译脚本
├── README.md # 测试文档
├── pocl_smoke.cpp # OpenCL基础功能测试
├── run_mnn_opencl.cpp # MNN OpenCL运行时测试
├── run_mnn_opencl_model.cpp # MNN模型推理测试
├── check_creator.cpp # RuntimeCreator验证
├── clrt_create.cpp # OpenCLRuntime创建测试
└── gen_tiny_matmul_add_onnx.py # ONNX模型生成脚本
5.2 OpenCL烟雾测试
文件:pocl_test/pocl_smoke.cpp
功能:验证OpenCL平台、设备和内核的基本功能
测试内容:
- 枚举OpenCL平台
- 查询平台信息(名称、厂商、版本)
- 枚举设备
- 创建上下文和命令队列
- 编译并运行简单的OpenCL内核
运行命令:
export LD_LIBRARY_PATH="./build_pocl_opencl:${LD_LIBRARY_PATH:-}"
./build_pocl_opencl/pocl_test/pocl_smoke
预期输出:
platforms=1
[0] name=Portable Computing Language
[0] vendor=The pocl project
[0] version=OpenCL 3.0 PoCL 7.1 Linux, Release, RELOC, LLVM 17.0.6, SLEEF, POCL_DEBUG
device0=cpu-cascadelake-Intel(R) Xeon(R) Platinum 8255C CPU @ 2.50GHz
result=2,3,4,5
5.3 MNN OpenCL模型测试
文件:pocl_test/run_mnn_opencl_model.cpp
功能:加载并运行MNN模型,验证OpenCL后端的推理功能
测试内容:
- 加载OpenCL后端插件
libMNN_CL.so - 创建MNN解释器
- 配置OpenCL后端
- 加载模型文件
- 执行推理
- 验证输出结果
运行命令:
export LD_LIBRARY_PATH="./build_pocl_opencl:${LD_LIBRARY_PATH:-}"
./build_pocl_opencl/pocl_test/run_mnn_opencl_model ./tiny_matmul_add.mnn
预期输出:
[MNN][OpenCL] OpenCLRuntime created (platform_size=1 platform_id=0 device_id=0 context_ptr=0x...)
[MNN][OpenCL] CLRuntime creation OK.
[MNN] RuntimeCreator found for type=3 (needCheck=0)
[MNN] RuntimeCreator validated for type=3 (onCreate ok)
runSession rc=0
y=[9.5,11.75,16]
5.4 严格模式测试
目的:验证所有计算操作都在OpenCL上执行,没有CPU回退
运行命令:
export MNN_STRICT_OPENCL_NO_CPU_OP=1
export LD_LIBRARY_PATH="./build_pocl_opencl:${LD_LIBRARY_PATH:-}"
./build_pocl_opencl/pocl_test/run_mnn_opencl_model ./tiny_matmul_add.mnn
预期输出:
[MNN][OpenCL] OpenCLRuntime created (platform_size=1 platform_id=0 device_id=0 context_ptr=0x...)
[MNN][OpenCL] CLRuntime creation OK.
[MNN] RuntimeCreator found for type=3 (needCheck=0)
[MNN] RuntimeCreator validated for type=3 (onCreate ok)
runSession rc=0
y=[9.5,11.75,16]
如果存在CPU回退:
[MNN][STRICT] OpenCL has no execution for op type=XXX name=XXX; CPU fallback disabled
六、问题排查
6.1 常见问题
问题1:找不到OpenCL平台
- 症状:
platforms=0 - 原因:PoCL未正确安装或未注册到ICD
- 解决:检查
/etc/OpenCL/vendors/pocl.icd文件,运行clinfo验证
问题2:OpenCLRuntime创建失败
- 症状:
[MNN][OpenCL] OpenCLRuntime create error - 原因:设备权限问题或PoCL配置错误
- 解决:检查设备权限,查看PoCL日志
问题3:链接错误
- 症状:
undefined reference to cl... - 原因:OpenCL库未正确链接
- 解决:确保
-lOpenCL或OpenCL::OpenCL正确配置
问题4:运行时找不到libMNN_CL.so
- 症状:
dlopen(libMNN_CL.so) failed - 原因:库路径未正确设置
- 解决:设置
LD_LIBRARY_PATH包含build_pocl_opencl/source/backend/opencl
问题5:模型转换失败
- 症状:
MNNConvert: error - 原因:ONNX模型格式不正确或依赖缺失
- 解决:使用
onnx.checker.check_model()验证ONNX模型,检查Python依赖
6.2 调试技巧
启用详细日志:
export POCL_DEBUG=1
export MNN_STRICT_OPENCL_NO_CPU_OP=1
检查OpenCL设备:
clinfo
验证库链接:
ldd ./build_pocl_opencl/pocl_test/run_mnn_opencl_model
验证ONNX模型:
python3 -c "import onnx; onnx.checker.check_model('tiny_matmul_add.onnx')"
查看MNN模型信息:
./build_conv/MNNConvert -f MNN --modelFile tiny_matmul_add.mnn --info
七、完整流程示例
7.1 从零开始的完整流程
# 1. 环境准备
sudo yum install -y gcc gcc-c++ cmake ninja-build git pocl pocl-devel ocl-icd ocl-icd-devel
pip install onnx numpy
# 2. 克隆MNN仓库
cd /root/workspace
git clone https://github.com/alibaba/MNN.git
cd MNN
# 3. 应用POCL适配补丁(如果需要)
git checkout pocl-integration
# 4. 编译MNNConvert工具
mkdir build_conv && cd build_conv
cmake .. -DMNN_BUILD_CONVERTER=ON
make -j$(nproc) MNNConvert
# 5. 生成测试模型
cd /root/workspace/mnn/pocl_test
python3 gen_tiny_matmul_add_onnx.py --out ../tiny_matmul_add.onnx
# 6. 转换为MNN格式
cd /root/workspace/mnn
./build_conv/MNNConvert -f ONNX --modelFile tiny_matmul_add.onnx --MNNModel tiny_matmul_add.mnn --bizCode MNN
# 7. 编译MNN和测试程序
bash pocl_test/build_opencl_pocl.sh
# 8. 运行测试
export LD_LIBRARY_PATH="./build_pocl_opencl:${LD_LIBRARY_PATH:-}"
./build_pocl_opencl/pocl_test/pocl_smoke
./build_pocl_opencl/pocl_test/run_mnn_opencl_model ./tiny_matmul_add.mnn
# 9. 严格模式测试
export MNN_STRICT_OPENCL_NO_CPU_OP=1
./build_pocl_opencl/pocl_test/run_mnn_opencl_model ./tiny_matmul_add.mnn
7.2 快速验证流程
# 如果已经编译完成,直接运行测试
cd /root/workspace/mnn
# 设置库路径
export LD_LIBRARY_PATH="./build_pocl_opencl:${LD_LIBRARY_PATH:-}"
# 运行OpenCL烟雾测试
./build_pocl_opencl/pocl_test/pocl_smoke
# 运行MNN模型测试
./build_pocl_opencl/pocl_test/run_mnn_opencl_model ./tiny_matmul_add.mnn
# 严格模式测试
export MNN_STRICT_OPENCL_NO_CPU_OP=1
./build_pocl_opencl/pocl_test/run_mnn_opencl_model ./tiny_matmul_add.mnn
八、总结
MNN适配POCL的主要工作包括:
- 设备检测适配:修改OpenCLRuntime以支持CPU设备
- 日志增强:添加详细的运行时创建日志
- 严格模式:实现禁止CPU回退的严格验证模式
- 编译配置:提供完整的编译脚本和CMake配置
- 测试验证:提供完整的测试程序和测试流程
- 模型转换:提供从ONNX到MNN的完整转换流程
通过这些修改,MNN可以在PoCL提供的CPU OpenCL环境中运行,为没有GPU的服务器提供了OpenCL后端的支持,同时通过严格模式确保了OpenCL后端的完整性验证。完整的模型转换流程使得用户可以轻松创建和测试自定义模型。
附录
A. Git提交记录
d1e110e (HEAD -> pocl-integration) Strict mode: don't disable CPU runtime; use per-op no-CPU fallback
43af54e Build/load MNN_CL plugin so OpenCL RuntimeCreator is available
2ca6812 Fix build_opencl_pocl.sh run paths for pocl_test executables
4da50d5 Fix: ensure MNN_CL objects and OpenCL libs are linked into MNN
ad37c51 Fix: force-link OpenCL backend objects into libMNN.so
8e85806 Use system OpenCL ICD loader by default in build_opencl_pocl.sh
ab92a99 Fix: link OpenCL libs into libMNN.so when MNN_OPENCL=ON
6243051 Fix pocl_test linking against built libMNN
6397566 Fix pocl_smoke build log buffer constness for C OpenCL API
fda76c6 (origin/master, origin/HEAD) Add Python script to generate tiny_matmul_add.onnx
ebd9474 Wire pocl_test into build and document build/model/test steps
2f39a4d Add build script for pocl_test OpenCL/PoCL validation
a8588f0 Add pocl_test demos for validating MNN OpenCL on PoCL
7efe831 OpenCL: support PoCL (CPU device) + strict no-CPU fallback
B. 相关文件路径
MNN/
├── patches/
│ └── mnn_pocl_integration.patch # POCL适配补丁
├── pocl_test/
│ ├── build_opencl_pocl.sh # 编译脚本
│ ├── CMakeLists.txt # 测试程序构建配置
│ ├── pocl_smoke.cpp # OpenCL烟雾测试
│ ├── run_mnn_opencl_model.cpp # MNN模型测试
│ ├── gen_tiny_matmul_add_onnx.py # ONNX模型生成
│ └── README.md # 测试文档
├── source/
│ ├── backend/opencl/core/
│ │ ├── OpenCLBackend.cpp # OpenCL后端
│ │ └── runtime/
│ │ └── OpenCLRuntime.cpp # OpenCL运行时
│ └── core/
│ ├── Backend.cpp # 后端管理
│ └── Pipeline.cpp # 执行管道
└── build_pocl_opencl/ # 编译输出目录
C. 环境变量说明
| 环境变量 | 说明 | 默认值 |
|---|---|---|
MNN_STRICT_NO_CPU_RUNTIME | 禁用CPU运行时创建 | 0 |
MNN_STRICT_OPENCL_NO_CPU_OP | 禁止操作级CPU回退 | 0 |
POCL_DEBUG | 启用PoCL调试日志 | 0 |
LD_LIBRARY_PATH | 库搜索路径 | - |
D. 参考资料
评论
加载评论中...