Исходник [MoonLoader] MoonCL - параллельное программирование в Lua на OpenCL (Pre-Release)

Loverxzc

Участник
Автор темы
46
23

MoonCL - либа для параллельных вычислений на видеоядре прямо в Lua скрипте.

Часть рутинного кода написана вместе с нейронкой, её код был проверен вручную, я знаком с такими понятиями, как: буффер, аллокация(alloc) и деаллокация(free), сборщик мусора и т. п. Полных тестов на стабильность не было. Вы имеете полное право закидать меня кокэшками за это.
Скрипт в пре-релизе, если есть какие-то замечания или предложения - Issues и Pull Requests ждут, буду рад получить помощь.
Много кто может задать вопрос: "А нахуя мне OpenCL, если есть effil?". И это справедливо подмечено, вся эта затея пришла в голову чисто случайно, сделано по приколу.
Возможно, эта либа даст кому-нибудь возможность сделать что-то абсурдное или глобальное, хз.


Дает возможность считать тяжелую математику параллельно на GPU через OpenCL 1.2 без фризов игры. Вся тяжелая работа выносится в асинхронную очередь, а скрипт просто опрашивает статус в тике. Для пары десятков или сотен проверок она не нужна - быстрее сделать обычным циклом или через FFI. Смысл появляется там, где надо пачками считать тысячи элементов: поиск дистанций, рейкасты по куче хитбоксов, пространственные фильтры или матричные трансформации точек.

Установка​

Кинуть папку moonloader в корень игры.
Получится примерно так:

moonloader/lib/mooncl/
├── init.lua
└── mooncl.dll

Вшитые ядра​

Базовые ядра уже внутри DLL:
  • batch_distance - дистанция от массива точек до одной целевой
  • ray_aabb_intersect - рейкаст луча по массиву хитбоксов (AABB), возвращает дистанцию или -1.0
  • mat4_transform_points - умножение массива float4 на матрицу 4x4
  • batch_spatial_filter - проверка радиуса, пишет маску 1/0
  • batch_clamp / batch_lerp - кламп и интерполяция массивов

Пример использования​

Считаем расстояния для 10 000 точек:
require("moonloader")
local mooncl = require("mooncl")
local ffi = require("ffi")

function main()
    while not isSampAvailable() do wait(0) end

    local ok, dev = mooncl.init()
    if not ok then return print("MoonCL init error: " .. dev) end
    print("MoonCL run on: " .. dev)

    local COUNT = 10000

    -- Данные в RAM
    local points = mooncl.new_float4_array(COUNT)
    for i = 0, COUNT - 1 do
        points[i].x, points[i].y, points[i].z, points[i].w = i, i * 0.5, 0.0, 1.0
    end

    -- Буферы в VRAM
    local in_buf = mooncl.create_buffer(COUNT * 16)
    local out_buf = mooncl.create_buffer(COUNT * 4)
    in_buf:write(points)

    -- Настройка ядра
    local kernel = mooncl.get_kernel("batch_distance")
    kernel:set_buffer(0, in_buf)
    kernel:set_float4(1, 0, 0, 0, 0)
    kernel:set_buffer(2, out_buf)
    kernel:set_int(3, COUNT)

    -- Считаем асинхронно
    local run_evt = kernel:run_async(COUNT)
    while not run_evt:is_done() do wait(0) end

    -- Забираем результат
    local results = ffi.new("float[?]", COUNT)
    local read_evt = out_buf:read_async(results)
    while not read_evt:is_done() do wait(0) end

    print("Result for 500: " .. results[500])
    -- Необязательно, но есть возможность вручную освободить память
    in_buf:free()
    out_buf:free()
    kernel:free()
end

Результат:
Снимок экрана_20260904_212408.png

Свои ядра

Если ты продвинутый гей, то можно скомпилировать любой свой код ядра на лету прямо в скрипте:

Lua:
local src = [[
__kernel void add(__global const float* a, __global const float* b, __global float* c, int count) {
    int id = get_global_id(0);
    if (id >= count) return;
    c[id] = a[id] + b[id];
}
]]

local kernel, err = mooncl.compile(src, "add")
if not kernel then return print("Compile error:\n" .. err) end


Исходник и инструкция:
 

MrCreepTon

Неизвестный
Всефорумный модератор
2,411
5,579
Ну как будто если для самп скрипта нужно использовать GPU, то либо алгоритм неэффективно написан, либо стоит кэшировать результаты.
Но как наличие такой возможности - круто
 
  • Нравится
Реакции: Loverxzc

Loverxzc

Участник
Автор темы
46
23
Ну как будто если для самп скрипта нужно использовать GPU, то либо алгоритм неэффективно написан, либо стоит кэшировать результаты.
Но как наличие такой возможности - круто
Армия бомжей-мунботов с симуляцией физики GTA SA с алгоритмом поиска путей на прокси, вот бы правда

Обновление 05.09.2026
v0.1.1-pre-release:

  • Пофикшена ошибка "CL_OUT_OF_HOST_MEMORY" после нескольких перезапусков скрипта.
  • Почищен код от мусора.
  • Добавлены названия ошибок в логах.
 
Последнее редактирование: