承接 rindow/rindow-opencl-ffi 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

rindow/rindow-opencl-ffi

Composer 安装命令:

composer require rindow/rindow-opencl-ffi

包简介

The OpenCL library for FFI on PHP

README 文档

README

Status: Build Status Downloads Latest Stable Version License

You can use OpenCL on PHP. The version of OpenCL is limited to version 1.2(1.1 with restrictions), and we are considering porting to a wide range of environments.

Since our goal is to use it with the Rindow Neural Network Library, we currently only have the minimum required functionality. It will be expanded in the future.

Please see the documents about Buffer objects on Rindow Mathematics web pages.

Requirements

  • PHP 8.1 or PHP8.2 or PHP8.3 or PHP8.4
  • interop-phpobjects/polite-math 1.0.5 or later
  • FFI-Buffer in the Interop php objects for Math. (ex. rindow/rindow-math-buffer-ffi)
  • OpenCL 1.2 ICL loader and OpenCL 1.1/1.2 drivers
  • Windows 10/11, Ubuntu(Recommendation 22.04-)/Debian (Recommendation 12-)

AMD GPU/APU and Intel integrated GPU drivers for Windows are including OpenCL drivers. If you want to use it on Linux, you need to explicitly install the OpenCL driver.

How to setup

Setup OpenCL

On Windows, you can use OpenCL without doing anything.

On Linux, install ICL Loader and the driver appropriate for your hardware.

For example, in the case of Linux standard AMD driver, install as follows

$ sudo apt install clinfo
$ sudo apt install mesa-opencl-icd

Linux standard OpenCL drivers include:

  • mesa-opencl-icd
  • beignet-opencl-icd
  • intel-opencl-icd
  • nvidia-opencl-icd-xxx
  • pocl-opencl-icd

Setup Rindow OpenCL-FFI

Install using composer.

$ composer require rindow/rindow-opencl-ffi

How to use

Let's run the sample program.

Sample for Display OpenCL Information

<?php
include __DIR__.'/vendor/autoload.php';

use Interop\Polite\Math\Matrix\OpenCL;
use Rindow\OpenCL\FFI\OpenCLFactory;

$ocl = new OpenCLFactory();
$platforms = $ocl->PlatformList();
$m = $platforms->count();
for($p=0;$p<$m;$p++) {
    echo "platform(".$p.")\n";
    echo "    CL_PLATFORM_NAME=".$platforms->getInfo($p,OpenCL::CL_PLATFORM_NAME)."\n";
    echo "    CL_PLATFORM_PROFILE=".$platforms->getInfo($p,OpenCL::CL_PLATFORM_PROFILE)."\n";
    echo "    CL_PLATFORM_VERSION=".$platforms->getInfo($p,OpenCL::CL_PLATFORM_VERSION)."\n";
    echo "    CL_PLATFORM_VENDOR=".$platforms->getInfo($p,OpenCL::CL_PLATFORM_VENDOR)."\n";
    $devices = $ocl->DeviceList($platforms,index:$p);
    $n = $devices->count();
    for($i=0;$i<$n;$i++) {
        echo "    device(".$i.")\n";
        echo "        CL_DEVICE_VENDOR_ID=".$devices->getInfo($i,OpenCL::CL_DEVICE_VENDOR_ID)."\n";
        echo "        CL_DEVICE_NAME=".$devices->getInfo($i,OpenCL::CL_DEVICE_NAME)."\n";
        echo "        CL_DEVICE_TYPE=(";
        $device_type = $devices->getInfo($i,OpenCL::CL_DEVICE_TYPE);
        if($device_type&OpenCL::CL_DEVICE_TYPE_CPU) { echo "CPU,"; }
        if($device_type&OpenCL::CL_DEVICE_TYPE_GPU) { echo "GPU,"; }
        if($device_type&OpenCL::CL_DEVICE_TYPE_ACCELERATOR) { echo "ACCEL,"; }
        if($device_type&OpenCL::CL_DEVICE_TYPE_CUSTOM) { echo "CUSTOM,"; }
        echo ")\n";
        echo "        CL_DEVICE_VENDOR=".$devices->getInfo($i,OpenCL::CL_DEVICE_VENDOR)."\n";
        echo "        CL_DEVICE_PROFILE=".$devices->getInfo($i,OpenCL::CL_DEVICE_PROFILE)."\n";
        echo "        CL_DEVICE_VERSION=".$devices->getInfo($i,OpenCL::CL_DEVICE_VERSION)."\n";
        echo "        CL_DEVICE_OPENCL_C_VERSION=".$devices->getInfo($i,OpenCL::CL_DEVICE_OPENCL_C_VERSION)."\n";
    }
}

Sample for Compile and Run OpenCL Program

$ composer require rindow/rindow-opencl-ffi
$ composer require rindow/rindow-math-buffer-ffi
<?php
include __DIR__.'/vendor/autoload.php';

use Interop\Polite\Math\Matrix\OpenCL;
use Interop\Polite\Math\Matrix\NDArray;
use Rindow\OpenCL\FFI\OpenCLFactory;
use Rindow\Math\Buffer\FFI\BufferFactory;

$ocl = new OpenCLFactory();
$hostBufferFactory = new BufferFactory();
$NWITEMS = 64;

$context = $ocl->Context(OpenCL::CL_DEVICE_TYPE_DEFAULT);
$queue = $ocl->CommandQueue($context);
$sources = [
    "__kernel void saxpy(const global float * x,\n".
    "                    __global float * y,\n".
    "                    const float a)\n".
    "{\n".
    "   uint gid = get_global_id(0);\n".
    "   y[gid] = a* x[gid] + y[gid];\n".
    "}\n"
];
$program = $ocl->Program($context,$sources);

try {
    $program->build();
} catch(\RuntimeException $e) {
    echo $e->getMessage()."\n";
    switch($e->getCode()) {
        case OpenCL::CL_BUILD_PROGRAM_FAILURE: {
            echo "CL_PROGRAM_BUILD_STATUS=".$program->getBuildInfo(OpenCL::CL_PROGRAM_BUILD_STATUS)."\n";
            echo "CL_PROGRAM_BUILD_OPTIONS=".safestring($program->getBuildInfo(OpenCL::CL_PROGRAM_BUILD_OPTIONS))."\n";
            echo "CL_PROGRAM_BUILD_LOG=".safestring($program->getBuildInfo(OpenCL::CL_PROGRAM_BUILD_LOG))."\n";
            echo "CL_PROGRAM_BINARY_TYPE=".safestring($program->getBuildInfo(OpenCL::CL_PROGRAM_BINARY_TYPE))."\n";
        }
        case OpenCL::CL_COMPILE_PROGRAM_FAILURE: {
            echo "CL_PROGRAM_BUILD_LOG=".safestring($program->getBuildInfo(OpenCL::CL_PROGRAM_BUILD_LOG))."\n";
        }
    }
    throw $e;
}
$kernel = $ocl->Kernel($program,"saxpy");
$hostX = $hostBufferFactory->Buffer(
    $NWITEMS,NDArray::float32
);
$hostY = $hostBufferFactory->Buffer(
    $NWITEMS,NDArray::float32
);

for($i=0;$i<$NWITEMS;$i++) {
    $hostX[$i] = $i;
    $hostY[$i] = $NWITEMS-1-$i;
}
$a = 2.0;
$bufX = $ocl->Buffer($context,intval($NWITEMS*32/8),
    OpenCL::CL_MEM_READ_ONLY|OpenCL::CL_MEM_COPY_HOST_PTR,
    $hostX);
$bufY = $ocl->Buffer($context,intval($NWITEMS*32/8),
    OpenCL::CL_MEM_READ_WRITE|OpenCL::CL_MEM_COPY_HOST_PTR,
    $hostY);
$kernel->setArg(0,$bufX);
$kernel->setArg(1,$bufY);
$kernel->setArg(2,$a,NDArray::float32);

// enqueueNDRange
$global_work_size = [$NWITEMS];
$local_work_size = [1];
$kernel->enqueueNDRange($queue,$global_work_size,$local_work_size);

// complete kernel
$queue->finish();

$bufY->read($queue,$hostY);

for($i=0;$i<$NWITEMS;$i++) {
    echo $hostY[$i].",";
}
echo "\n";

To Do

We have never verified OpenCL functionality on macOS. As OpenCL is not the recommended approach on macOS, it's a lower priority, but we welcome assistance from anyone who can test in a macOS environment.

rindow/rindow-opencl-ffi 适用场景与选型建议

rindow/rindow-opencl-ffi 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 664 次下载、GitHub Stars 达 4, 最近一次更新时间为 2024 年 03 月 18 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「ffi」 「rindow」 「opencl」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 rindow/rindow-opencl-ffi 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 rindow/rindow-opencl-ffi 我们能提供哪些服务?
定制开发 / 二次开发

基于 rindow/rindow-opencl-ffi 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 664
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 4
  • 点击次数: 25
  • 依赖项目数: 2
  • 推荐数: 0

GitHub 信息

  • Stars: 4
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: BSD-3-Clause
  • 更新时间: 2024-03-18