From 88c57b41cd53a2ec7268a6c8b33713d1f8004855 Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Tue, 21 Apr 2026 19:40:02 +0300 Subject: [PATCH 01/25] made lib compare --- src/opencl/Compare.md | 109 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/opencl/Compare.md diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md new file mode 100644 index 000000000..17c9a5e07 --- /dev/null +++ b/src/opencl/Compare.md @@ -0,0 +1,109 @@ +# Сравнение библиотек для создания механизма конфигурирования +Вся информация взята из репозиториев соответствующих проектов. Дата обращения: 21.04.26. + +## Критерии сравнения + +| Критерий | Метрика | Единицы измерения | +|:---|:---|:---| +| **Зависимости** | количество, суммарный размер | n, MiB | +| **Источники** | CLI (argv) / env / файлы | +/-, форматы | +| **Стандарт C++** | минимальная версия | C++хх | +| **Пакетные менеджеры** | vcpkg / Conan / Conda / apt / brew / pacman | +/- | +| **Способ распространения** | header-only / статическая / динамическая | — | +| **ОС** | Linux / Windows / macOS | +/-, компиляторы | +| **Активность** | среднее число коммитов | коммитов/мес (за последний мес) | +| **Issues** | open, closed/open | n, коэффициент | +| **Сообщество** | GitHub Stars | n | + + + +## Сравнение парсеров командной строки (CLI) + +| Критерий | CLI11 | cxxopts | +|:---|:---:|:---:| +| Зависимости (n, MiB) | 0, 0 | 0, 0 | +| **Источники** | | | +|  CLI (argv) | + | + | +|  env | + | - | +|  Файлы | INI, TOML¹ | - | +| Стандарт C++ | ≥ C++11 | ≥ C++11 | +| **Пакетные менеджеры** | | | +|  vcpkg | + | + | +|  Conan | + | + | +|  Conda | + | ? | +|  apt | ? | ? | +|  brew | ? | + | +|  pacman | ? | ? | +| Способ распространения | header-only | header-only +| **ОС** | | | +|  Linux | + (GCC 4.8+, Clang 3.5+) | + (GCC ≥ 4.9, Clang ≥ 3.1) | +|  Windows | + (MSVC ≥ 2015) | + (MSVC ≥ 2015) | +|  macOS | + (AppleClang 7+) | + (Clang ≥ 3.1 с libc++) | +| **Сообщество** | | | +|  Активность (коммитов/мес) | 4 | 1 | +|  Issues всего | 506 | 307 | +|  Issues closed/open | 9 | 6 | +|  Stars | 4.3k | 4.7k | + + +> ¹ CLI11 поддерживает env с версии 2.4.0, файлы INI/TOML читает как опции командной строки. + +## Парсеры файлов + +| Критерий | nlohmann/json | yaml-cpp | toml++ | toml11 | +|:---|:---:|:---:|:---:|:---:| +| Зависимости (n, MiB) | 0, 0 | 0, 0 | 0, 0 | 0, 0 +| **Источники** | | | +|  CLI (argv) | - | - | - | - +|  env | - | - | - | - +|  Файлы | JSON | YAML | TOML | TOML +| Стандарт C++ | ≥ C++11 | ≥ C++11 | ≥ C++17 | ≥ C++11 +| **Пакетные менеджеры** | | | +|  vcpkg | + | + | + | + +|  Conan | + | + | + | ? +|  Conda | + | + | ? | ? +|  apt | + | + | ? | ? +|  brew | + | + | ? | ? +|  pacman | + | + | ? | ? | +| Способ распространения | header-only | статическая/динамическая¹ | header-only/статическая/динамическая¹ | header-only/статическая/динамическая¹ +| **ОС** | | | +|  Linux | + (GCC 4.8–14.2, Clang 3.4–21.0) | + (GCC, Clang) | + (Clang 8+, GCC 8+) | + (GCC, Clang) +|  Windows | + (MSVC 2015–2022) | + (MSVC) | + (MSVC VS2019+) | + (MSVC, MinGW) +|  macOS | + (AppleClang 9.1–16.0) | + (Xcode, AppleClang) | + (AppleClang) | + (AppleClang) +| **Сообщество** | | | +|  Активность (коммитов/мес) | 2 | 9 | 2 | 4 +|  Issues всего | 3271 | 905 | 193 | 194 +|  Issues closed/open | 68 | 3 | 8 | 5 +|  Stars | 49.4k | 15k | 2k | 1.3k + +> ¹ Опционально. + +## Сравнение универсальных инструментов + +| Критерий | Boost +|:---|:---:| +| Зависимости (n, MiB) | 0, ~192 | +| **Источники** | | | +|  CLI (argv) | + | + | +|  env | + | + | +|  Файлы | INI, JSON, XML, TOML | +| Стандарт C++ | ≥ C++11 | ≥ C++11 | +| **Пакетные менеджеры** | | | +|  vcpkg | + | +|  Conan | + | +|  Conda | + | +|  apt | + | +|  brew | + | +|  pacman | + | +| Способ распространения | header-only/статическая/динамическая¹ | +| **ОС** | | | +|  Linux | + (GCC 5+, Clang 3.6+) | +|  Windows | + (MSVC 2015 (vc140)) | +|  macOS | + (AppleClang) | +| **Сообщество** | | | +|  Активность (коммитов/мес) | 12 | +|  Issues всего | 400 | +|  Issues closed/open | 1 | +|  Stars | 9.4k | + +> ¹ Опционально. \ No newline at end of file From f6c9ff12a39f5bf03d106c10295243a238c529da Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Sat, 25 Apr 2026 22:59:16 +0300 Subject: [PATCH 02/25] added more comparison points --- src/opencl/Compare.md | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index 17c9a5e07..7a6634642 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -5,9 +5,10 @@ | Критерий | Метрика | Единицы измерения | |:---|:---|:---| -| **Зависимости** | количество, суммарный размер | n, MiB | +| **Зависимости** | наличие | +/- | | **Источники** | CLI (argv) / env / файлы | +/-, форматы | | **Стандарт C++** | минимальная версия | C++хх | +| **Поддерживает стандарт иерархии** | Linux/Windows/MacOS | +/- | | **Пакетные менеджеры** | vcpkg / Conan / Conda / apt / brew / pacman | +/- | | **Способ распространения** | header-only / статическая / динамическая | — | | **ОС** | Linux / Windows / macOS | +/-, компиляторы | @@ -19,14 +20,18 @@ ## Сравнение парсеров командной строки (CLI) -| Критерий | CLI11 | cxxopts | +| Критерий | CLI11 | cxxopts | |:---|:---:|:---:| -| Зависимости (n, MiB) | 0, 0 | 0, 0 | +| Зависимости | - | - | | **Источники** | | | |  CLI (argv) | + | + | |  env | + | - | -|  Файлы | INI, TOML¹ | - | +|  Файлы | - | - | | Стандарт C++ | ≥ C++11 | ≥ C++11 | +| **Поддерживает стандарт иерархии** | | | +|  Linux | + | + | +|  Windows | + | + | +|  MacOS | + | + | | **Пакетные менеджеры** | | | |  vcpkg | + | + | |  Conan | + | + | @@ -46,18 +51,20 @@ |  Stars | 4.3k | 4.7k | -> ¹ CLI11 поддерживает env с версии 2.4.0, файлы INI/TOML читает как опции командной строки. - ## Парсеры файлов | Критерий | nlohmann/json | yaml-cpp | toml++ | toml11 | |:---|:---:|:---:|:---:|:---:| -| Зависимости (n, MiB) | 0, 0 | 0, 0 | 0, 0 | 0, 0 +| Зависимости | - | - | - | - | **Источники** | | | |  CLI (argv) | - | - | - | - |  env | - | - | - | - |  Файлы | JSON | YAML | TOML | TOML | Стандарт C++ | ≥ C++11 | ≥ C++11 | ≥ C++17 | ≥ C++11 +| **Поддерживает стандарт иерархии** | | | +|  Linux | + | + | + | + | +|  Windows | + | + | + | + | +|  MacOS | + | + | + | + | | **Пакетные менеджеры** | | | |  vcpkg | + | + | + | + |  Conan | + | + | + | ? @@ -80,14 +87,18 @@ ## Сравнение универсальных инструментов -| Критерий | Boost +| Критерий | Boost.Program_options |:---|:---:| -| Зависимости (n, MiB) | 0, ~192 | +| Зависимости | + | | **Источники** | | | |  CLI (argv) | + | + | |  env | + | + | -|  Файлы | INI, JSON, XML, TOML | -| Стандарт C++ | ≥ C++11 | ≥ C++11 | +|  Файлы | INI | +| Стандарт C++ | ≥ C++3 | +| **Поддерживает стандарт иерархии** | | | +|  Linux | + | +|  Windows | + | +|  MacOS | + | | **Пакетные менеджеры** | | | |  vcpkg | + | |  Conan | + | @@ -95,10 +106,10 @@ |  apt | + | |  brew | + | |  pacman | + | -| Способ распространения | header-only/статическая/динамическая¹ | +| Способ распространения | статическая/динамическая¹ | | **ОС** | | | |  Linux | + (GCC 5+, Clang 3.6+) | -|  Windows | + (MSVC 2015 (vc140)) | +|  Windows | + (MSVC 2015 (vc140)+) | |  macOS | + (AppleClang) | | **Сообщество** | | | |  Активность (коммитов/мес) | 12 | @@ -106,4 +117,8 @@ |  Issues closed/open | 1 | |  Stars | 9.4k | -> ¹ Опционально. \ No newline at end of file +> ¹ Опционально. + + +## Итог: +По результатам сравнения, вероятно, лучшим вариантом будет использование `CLI11` и `nlohmann/json`, так как они, в отличие от Boost.program_options, не требуют зависимостей и являются header-only. \ No newline at end of file From 7419e1637cad00d327c0e9a8ac596258d115be37 Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Tue, 28 Apr 2026 17:03:26 +0300 Subject: [PATCH 03/25] added list of dependences --- src/opencl/Compare.md | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index 7a6634642..705b1dbca 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -15,6 +15,7 @@ | **Активность** | среднее число коммитов | коммитов/мес (за последний мес) | | **Issues** | open, closed/open | n, коэффициент | | **Сообщество** | GitHub Stars | n | +| **Проходит ли CI** | CI | +/- | @@ -49,6 +50,7 @@ |  Issues всего | 506 | 307 | |  Issues closed/open | 9 | 6 | |  Stars | 4.3k | 4.7k | +| **Проходит ли CI** | CI | + | + | ## Парсеры файлов @@ -82,6 +84,7 @@ |  Issues всего | 3271 | 905 | 193 | 194 |  Issues closed/open | 68 | 3 | 8 | 5 |  Stars | 49.4k | 15k | 2k | 1.3k +| **Проходит ли CI** | CI | + | + | - | + | > ¹ Опционально. @@ -89,7 +92,7 @@ | Критерий | Boost.Program_options |:---|:---:| -| Зависимости | + | +| Зависимости | +¹ | | **Источники** | | | |  CLI (argv) | + | + | |  env | + | + | @@ -106,7 +109,7 @@ |  apt | + | |  brew | + | |  pacman | + | -| Способ распространения | статическая/динамическая¹ | +| Способ распространения | статическая/динамическая² | | **ОС** | | | |  Linux | + (GCC 5+, Clang 3.6+) | |  Windows | + (MSVC 2015 (vc140)+) | @@ -116,8 +119,23 @@ |  Issues всего | 400 | |  Issues closed/open | 1 | |  Stars | 9.4k | +| **Проходит ли CI** | CI | + | -> ¹ Опционально. +> ¹ Список зависимостей: +1. Boost.Any +2. Boost.Bind +3. Boost.Config +4. Boost.Core +5. Boost.Detail +6. Boost.Function +7. Boost.Iterator +8. Boost.Lexical Cast +9. Boost.Smart Ptr +10. Boost.ThrowException +11. Boost.Tokenizer +12. Boost.Type Traits + +> ² Опционально. ## Итог: From 21279b013f3d124a579a75f786f3cc7dcd1f36bf Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Wed, 29 Apr 2026 03:48:13 +0300 Subject: [PATCH 04/25] CI -> + --- src/opencl/Compare.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index 705b1dbca..e0d144d1e 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -50,7 +50,7 @@ |  Issues всего | 506 | 307 | |  Issues closed/open | 9 | 6 | |  Stars | 4.3k | 4.7k | -| **Проходит ли CI** | CI | + | + | +| **Проходит ли CI** | + | + | + | ## Парсеры файлов @@ -84,7 +84,7 @@ |  Issues всего | 3271 | 905 | 193 | 194 |  Issues closed/open | 68 | 3 | 8 | 5 |  Stars | 49.4k | 15k | 2k | 1.3k -| **Проходит ли CI** | CI | + | + | - | + | +| **Проходит ли CI** | + | + | + | - | + | > ¹ Опционально. @@ -119,7 +119,7 @@ |  Issues всего | 400 | |  Issues closed/open | 1 | |  Stars | 9.4k | -| **Проходит ли CI** | CI | + | +| **Проходит ли CI** | + | + | > ¹ Список зависимостей: 1. Boost.Any From e2a2ad1a96cb9c3a8984f296e292818ed903e9ca Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Wed, 29 Apr 2026 03:53:50 +0300 Subject: [PATCH 05/25] Just formatting changes to README --- src/opencl/Compare.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index e0d144d1e..96bfff750 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -122,21 +122,21 @@ | **Проходит ли CI** | + | + | > ¹ Список зависимостей: -1. Boost.Any -2. Boost.Bind -3. Boost.Config -4. Boost.Core -5. Boost.Detail -6. Boost.Function -7. Boost.Iterator -8. Boost.Lexical Cast -9. Boost.Smart Ptr -10. Boost.ThrowException -11. Boost.Tokenizer -12. Boost.Type Traits +> 1. Boost.Any +> 2. Boost.Bind +> 3. Boost.Config +> 4. Boost.Core +> 5. Boost.Detail +> 6. Boost.Function +> 7. Boost.Iterator +> 8. Boost.Lexical Cast +> 9. Boost.Smart Ptr +> 10. Boost.ThrowException +> 11. Boost.Tokenizer +> 12. Boost.Type Traits > ² Опционально. ## Итог: -По результатам сравнения, вероятно, лучшим вариантом будет использование `CLI11` и `nlohmann/json`, так как они, в отличие от Boost.program_options, не требуют зависимостей и являются header-only. \ No newline at end of file +По результатам сравнения, вероятно, лучшим вариантом будет использование `CLI11` и `nlohmann/json`, так как они, в отличие от `Boost.program_options`, не требуют зависимостей и являются header-only. \ No newline at end of file From 2ed3b039ffa9ef2d16b59aa24961341eb70642b1 Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Mon, 4 May 2026 05:53:20 +0300 Subject: [PATCH 06/25] added config params info --- src/opencl/Compare.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index 96bfff750..77ff795ee 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -139,4 +139,33 @@ ## Итог: -По результатам сравнения, вероятно, лучшим вариантом будет использование `CLI11` и `nlohmann/json`, так как они, в отличие от `Boost.program_options`, не требуют зависимостей и являются header-only. \ No newline at end of file +По результатам сравнения, вероятно, лучшим вариантом будет использование `CLI11` и `nlohmann/json`, так как они, в отличие от `Boost.program_options`, не требуют зависимостей и являются header-only. + + +# Что нужно конфигурировать +1. Выбор платформы +2. Выбор устройства +3. Количество очередей: сейчас создается только 1 очередь +4. Приоритеты очередей +5. Размер линейного аллокатора `DEFAULT_SIZE` +6. Стратегия выбора аллокатора: \ + NVIDIA используют общий аллокатор \ + Все остальные используем линейный аллокатор +7. Характеристики устройтсв:\ + `m_vendor_id` \ + `m_max_cu` \ + `m_default_wgs` \ + `m_max_local_mem` \ + `m_addr_align` \ + пороги `m_max_wgs`, `m_max_cu`, `m_wave_size` +8. Строковые паттерны проверки девайса: возможно только 3 вариаета `m_vendor_name` +6. Дефолтные значения характеристик \ + `m_addr_align` \ + `m_default_wgs` \ + `uint m_wave_size` \ + `uint m_num_of_mem_banks` +7. Суффикс и имя \ + `m_name` \ + `m_suffix ` +8. Тип устройства (чтобы можно было использовать CPU) + `getDevices` \ No newline at end of file From fc33885d6d39fed790e25d6d9a1e7ed27748ed13 Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Mon, 4 May 2026 22:18:32 +0300 Subject: [PATCH 07/25] added config structure --- src/opencl/Compare.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index 77ff795ee..7eaf8c6d3 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -168,4 +168,36 @@ `m_name` \ `m_suffix ` 8. Тип устройства (чтобы можно было использовать CPU) - `getDevices` \ No newline at end of file + `getDevices` + +# Структура конфига (JSON) + +```bash +config: + + "platform": + "selection": + "user_alias": string + "official_name": string + "vendor": "nvidia" | "amd" | "intel" | "img" | "" + "index": int + "priority": int + "fallback": (???) # Нужен ли fallback + + "device": { + "selection": + "user_alias": string + "official_name": string + "type": "gpu" | "cpu" | "accelerator" | "all" + "index": int + "priority": int + "naming": + "accelerator_name" # m_name + "cache_suffix" # m_suffix + "tuning": + "default_work_group_size": int # m_default_wgs + "wave_size": int # m_wave_size + "memory_banks": int # m_num_of_mem_banks + "memory_alignment": int # m_addr_align + "fallback": (???) # Нужен ли fallback +``` \ No newline at end of file From d6809498459635cc7f34f5a24fb0a62e01258776 Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Mon, 4 May 2026 22:23:01 +0300 Subject: [PATCH 08/25] formatting only --- src/opencl/Compare.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index 7eaf8c6d3..6145cccf4 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -188,7 +188,7 @@ config: "selection": "user_alias": string "official_name": string - "type": "gpu" | "cpu" | "accelerator" | "all" + "type": "gpu" | "cpu" "index": int "priority": int "naming": From de27aa71c3eee3f402d965257db681f20fb51b84 Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Mon, 4 May 2026 22:36:23 +0300 Subject: [PATCH 09/25] added performance parameter --- src/opencl/Compare.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index 6145cccf4..3d063e800 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -184,7 +184,7 @@ config: "priority": int "fallback": (???) # Нужен ли fallback - "device": { + "device": "selection": "user_alias": string "official_name": string @@ -200,4 +200,14 @@ config: "memory_banks": int # m_num_of_mem_banks "memory_alignment": int # m_addr_align "fallback": (???) # Нужен ли fallback + + "performance" + "memory" + "linear_allocator_size_mb": int # DEFAULT_SIZE + "allocator_strategy": string # "auto" | "linear" | "general" | "vendor" + "vendor_strategy": + "nvidia": string # "linear" | "general" + "amd": string # "linear" | "general" + "intel": string # "linear" | "general" + "img": strings # "linear" | "general" ``` \ No newline at end of file From e0c9b47137ba531a84748e1924946c31ce71cc6f Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Mon, 4 May 2026 22:38:09 +0300 Subject: [PATCH 10/25] formatting only --- src/opencl/Compare.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index 3d063e800..0763f1590 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -204,10 +204,10 @@ config: "performance" "memory" "linear_allocator_size_mb": int # DEFAULT_SIZE - "allocator_strategy": string # "auto" | "linear" | "general" | "vendor" + "allocator_strategy": "auto" | "linear" | "general" | "vendor" "vendor_strategy": - "nvidia": string # "linear" | "general" - "amd": string # "linear" | "general" - "intel": string # "linear" | "general" - "img": strings # "linear" | "general" + "nvidia": "linear" | "general" + "amd": "linear" | "general" + "intel": "linear" | "general" + "img": "linear" | "general" ``` \ No newline at end of file From 0b8ca4945d2a6e3b944b098e171bd02a368930fe Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Tue, 5 May 2026 18:35:26 +0300 Subject: [PATCH 11/25] formatting --- src/opencl/Compare.md | 52 +++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index 0763f1590..d5ff3481e 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -183,31 +183,29 @@ config: "index": int "priority": int "fallback": (???) # Нужен ли fallback - - "device": - "selection": - "user_alias": string - "official_name": string - "type": "gpu" | "cpu" - "index": int - "priority": int - "naming": - "accelerator_name" # m_name - "cache_suffix" # m_suffix - "tuning": - "default_work_group_size": int # m_default_wgs - "wave_size": int # m_wave_size - "memory_banks": int # m_num_of_mem_banks - "memory_alignment": int # m_addr_align - "fallback": (???) # Нужен ли fallback - - "performance" - "memory" - "linear_allocator_size_mb": int # DEFAULT_SIZE - "allocator_strategy": "auto" | "linear" | "general" | "vendor" - "vendor_strategy": - "nvidia": "linear" | "general" - "amd": "linear" | "general" - "intel": "linear" | "general" - "img": "linear" | "general" + "device": + "selection": + "user_alias": string + "official_name": string + "type": "gpu" | "cpu" + "index": int + "priority": int + "naming": + "accelerator_name" # m_name + "cache_suffix" # m_suffix + "tuning": + "default_work_group_size": int # m_default_wgs + "wave_size": int # m_wave_size + "memory_banks": int # m_num_of_mem_banks + "memory_alignment": int # m_addr_align + "fallback": (???) # Нужен ли fallback + "performance" + "memory" + "linear_allocator_size_mb": int # DEFAULT_SIZE + "allocator_strategy": "auto" | "linear" | "general" | "vendor" + "vendor_strategy": + "nvidia": "linear" | "general" + "amd": "linear" | "general" + "intel": "linear" | "general" + "img": "linear" | "general" ``` \ No newline at end of file From b880e9eb83a28485a7efa538c78f950c518bf754 Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Tue, 5 May 2026 22:04:53 +0300 Subject: [PATCH 12/25] =?UTF-8?q?added=202=20libs,=20removed=20'=D0=9F?= =?UTF-8?q?=D0=B0=D0=BA=D0=B5=D1=82=D0=BD=D1=8B=D0=B5=20=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D0=B4=D0=B6=D0=B5=D1=80=D1=8B'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/opencl/Compare.md | 69 +++++++++++++++---------------------------- 1 file changed, 24 insertions(+), 45 deletions(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index d5ff3481e..f8bad3444 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -9,7 +9,6 @@ | **Источники** | CLI (argv) / env / файлы | +/-, форматы | | **Стандарт C++** | минимальная версия | C++хх | | **Поддерживает стандарт иерархии** | Linux/Windows/MacOS | +/- | -| **Пакетные менеджеры** | vcpkg / Conan / Conda / apt / brew / pacman | +/- | | **Способ распространения** | header-only / статическая / динамическая | — | | **ОС** | Linux / Windows / macOS | +/-, компиляторы | | **Активность** | среднее число коммитов | коммитов/мес (за последний мес) | @@ -17,6 +16,7 @@ | **Сообщество** | GitHub Stars | n | | **Проходит ли CI** | CI | +/- | +> ? - не указано в README. ## Сравнение парсеров командной строки (CLI) @@ -33,13 +33,6 @@ |  Linux | + | + | |  Windows | + | + | |  MacOS | + | + | -| **Пакетные менеджеры** | | | -|  vcpkg | + | + | -|  Conan | + | + | -|  Conda | + | ? | -|  apt | ? | ? | -|  brew | ? | + | -|  pacman | ? | ? | | Способ распространения | header-only | header-only | **ОС** | | | |  Linux | + (GCC 4.8+, Clang 3.5+) | + (GCC ≥ 4.9, Clang ≥ 3.1) | @@ -50,41 +43,34 @@ |  Issues всего | 506 | 307 | |  Issues closed/open | 9 | 6 | |  Stars | 4.3k | 4.7k | -| **Проходит ли CI** | + | + | + | +| Проходит ли CI | + | + | + | ## Парсеры файлов -| Критерий | nlohmann/json | yaml-cpp | toml++ | toml11 | -|:---|:---:|:---:|:---:|:---:| -| Зависимости | - | - | - | - -| **Источники** | | | -|  CLI (argv) | - | - | - | - -|  env | - | - | - | - -|  Файлы | JSON | YAML | TOML | TOML -| Стандарт C++ | ≥ C++11 | ≥ C++11 | ≥ C++17 | ≥ C++11 -| **Поддерживает стандарт иерархии** | | | -|  Linux | + | + | + | + | -|  Windows | + | + | + | + | -|  MacOS | + | + | + | + | -| **Пакетные менеджеры** | | | -|  vcpkg | + | + | + | + -|  Conan | + | + | + | ? -|  Conda | + | + | ? | ? -|  apt | + | + | ? | ? -|  brew | + | + | ? | ? -|  pacman | + | + | ? | ? | -| Способ распространения | header-only | статическая/динамическая¹ | header-only/статическая/динамическая¹ | header-only/статическая/динамическая¹ +| Критерий | nlohmann/json | yaml-cpp | toml++ | toml11 | config-cxx | taocpp/config +|:---|:---:|:---:|:---:|:---:|:---:|:---:| +| Зависимости | - | - | - | - | - | - | +| **Источники** | +|  CLI (argv) | - | - | - | - | - | - | +|  env | - | - | - | - | + | + | +|  Файлы | JSON | YAML | TOML | TOML | JSON, YAML, XML | JSON, JAXN | +| Стандарт C++ | ≥ C++11 | ≥ C++11 | ≥ C++17 | ≥ C++11 | ≥ C++20 | ≥ C++17 | +| **Поддерживает стандарт иерархии** | +|  Linux | + | + | + | + | + | + | +|  Windows | + | + | + | + | + | + | +|  MacOS | + | + | + | + | + | + | +| Способ распространения | header-only | статическая/динамическая¹ | header-only/статическая/динамическая¹ | header-only/статическая/динамическая¹ | header-only | header-only | | **ОС** | | | -|  Linux | + (GCC 4.8–14.2, Clang 3.4–21.0) | + (GCC, Clang) | + (Clang 8+, GCC 8+) | + (GCC, Clang) -|  Windows | + (MSVC 2015–2022) | + (MSVC) | + (MSVC VS2019+) | + (MSVC, MinGW) -|  macOS | + (AppleClang 9.1–16.0) | + (Xcode, AppleClang) | + (AppleClang) | + (AppleClang) +|  Linux | + (GCC 4.8–14.2, Clang 3.4–21.0) | + (GCC, Clang) | + (Clang 8+, GCC 8+) | + (GCC, Clang) | + (GCC 13+, Clang 16+) | + +|  Windows | + (MSVC 2015–2022) | + (MSVC) | + (MSVC VS2019+) | + (MSVC, MinGW) | + (MSVC 143+ (VS 2022)) | + +|  macOS | + (AppleClang 9.1–16.0) | + (Xcode, AppleClang) | + (AppleClang) | + (AppleClang) | + (AppleClang 16+) | + | **Сообщество** | | | -|  Активность (коммитов/мес) | 2 | 9 | 2 | 4 -|  Issues всего | 3271 | 905 | 193 | 194 -|  Issues closed/open | 68 | 3 | 8 | 5 -|  Stars | 49.4k | 15k | 2k | 1.3k -| **Проходит ли CI** | + | + | + | - | + | +|  Активность (коммитов/мес) | 2 | 9 | 2 | 4 | 2 | 13 | +|  Issues всего | 3271 | 905 | 193 | 194 | 24 | 5 | +|  Issues closed/open | 68 | 3 | 8 | 5 | 0 open | 0 open | +|  Stars | 49.4k | 15k | 2k | 1.3k | 31 | 194 | +| Проходит ли CI | + | + | + | - | + | ? | > ¹ Опционально. @@ -102,13 +88,6 @@ |  Linux | + | |  Windows | + | |  MacOS | + | -| **Пакетные менеджеры** | | | -|  vcpkg | + | -|  Conan | + | -|  Conda | + | -|  apt | + | -|  brew | + | -|  pacman | + | | Способ распространения | статическая/динамическая² | | **ОС** | | | |  Linux | + (GCC 5+, Clang 3.6+) | @@ -119,7 +98,7 @@ |  Issues всего | 400 | |  Issues closed/open | 1 | |  Stars | 9.4k | -| **Проходит ли CI** | + | + | +| Проходит ли CI | + | + | > ¹ Список зависимостей: > 1. Boost.Any From e0c730b9044224d95e85fb3ac15fb9306fd8721f Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Mon, 11 May 2026 16:17:12 +0300 Subject: [PATCH 13/25] added SPLA usage scenarios --- src/opencl/Compare.md | 61 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index f8bad3444..2850c0048 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -120,6 +120,61 @@ ## Итог: По результатам сравнения, вероятно, лучшим вариантом будет использование `CLI11` и `nlohmann/json`, так как они, в отличие от `Boost.program_options`, не требуют зависимостей и являются header-only. +# Сценарии использования spla: +**Что важно всем:** возможность выбрать платформу и устройство + +1. Пользователь хочет решить свою задачу + - Неподготовленный пользователь + - важно: + - быстрая настройка через флаги + - что конфигурировать: + - уменьшить количество отладочной информации + - остальное - дефолтные параметры + - Опытный пользователь: + - важно: + - детальная ручная конфигурация параметров через конфигурационный файл + - ускорение вычислений с разреженными данными + - что конфигурировать: + - управление кэшем + - кастомные аллокаторы для разных форматов данных + - управление очередями команд + - Wave size override + - Work-group size + - оптимизация доступа к глобальной памяти + - управление логированием +2. Разработчик spla + - Отладчик, тестировик + - важно: + - верификация корректности работы на разных устройствах + - воспроизводимость ошибок + - что конфигурировать: + - возможность работать только на 1 гпу + - подробное логирование + - отключение кэша для принудительной перекомпиляции + - тестирование на неподдерживаемых вендорах без падения с ошибкой + - Бенчмаркер + - важно: + - минимизация шума при измерениях + - воспроизводимость результатов + - сравнение разных конфигураций + - что конфигурировать: + - профайлинг очередей `CL_QUEUE_PROFILING_ENABLE` + - сбор статистики и уменьшение шума `CLCounterPool` + - количество очередей для измерения параллелизма + - линейный аллокатор для предсказуемости памяти + - Wave size override + - Work-group size + - оптимизация доступа к глобальной памяти + - Расширяющий функциональность + - важно: + - возможность встроить код в существующую инфраструктуру + - чтобы новый код работал на всех устройтсвах + - что конфигурировать: + - включение кэша + - кастомные аллокаторы для разных форматов данных + - управление очередями + - Wave size override + - Work-group size # Что нужно конфигурировать 1. Выбор платформы @@ -187,4 +242,8 @@ config: "amd": "linear" | "general" "intel": "linear" | "general" "img": "linear" | "general" -``` \ No newline at end of file + "queues": + "count": int + +``` + From b5b7580f35e745752840db73949b0da1fc20e93a Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Tue, 19 May 2026 04:47:04 +0300 Subject: [PATCH 14/25] making defolt scenario --- src/opencl/Compare.md | 103 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index 2850c0048..4baf8f051 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -121,8 +121,109 @@ По результатам сравнения, вероятно, лучшим вариантом будет использование `CLI11` и `nlohmann/json`, так как они, в отличие от `Boost.program_options`, не требуют зависимостей и являются header-only. # Сценарии использования spla: -**Что важно всем:** возможность выбрать платформу и устройство +## Дефолтный сценарий + +Дефолтный сценарий должен решать главную задачу библиотеки: ускорение вычислений. + +### Выбор платформы и устройства + +Сначала следует выбрать наиболее подходящий девайс. Для этого необходимо пройти по всем платформам, собрать все устройства каждой платформы и среди них выбрать лучший. + +Выбранное устройство должно удовлетворять следующим критериям: +1. физически существовать у пользователя + +2. проходить базовые проверки: \ + - запрос размера глобальной памяти \ + - попытка выделить и освободить буфер + +Из всех рабочих и доступных устройств необходимо выбрать наиболее быстрое. Выбор осуществляется по следующей иерархии: + +1. Внешняя GPU (eGPU) + +2. Дискретная GPU (dGPU) + +3. Интегрированная GPU (iGPU) + +4. Запуск на CPU (при отсутствии GPU) + +При наличии нескольких GPU одного типа на каждом из них запускаются микробенчмарки с эталонной задачей, характерной для SPLA. В итоге выбирается GPU, показавшая лучшие результаты, и соответствующая ей платформа. + +Данный подход решает потенциальную проблему, когда девайс указан в OpenCL-платформе, но фактически отсутствует в системе. + +-- + +Нужно ли как-то учитывать параметры платформ? + +Логирование: Выдавать всю информацию (какие стандарты логирования? какая иерархия ошибок?) + +Бенчмарки: \ +Какую задачу прогонять? \ +Как вести замеры? \ +Подбор колтчества очередей: k = (t_вычислений)/ t_общ \ +если k = 0.5 => 1 очередь \ +если k >> 0.5 => ускорять передачу данных? \ +еслм k << 0. => ускорять вычисления? + +как подбирать оптимально \ +пользовательское количество потоков work group size \ +способ аллокации памяти и размер аллокатора +### Настройка очередей команд + +### Логирование + +### Тестовые бенчмарки + + +## Пользователь, который хочет решить свою задачу, используя spla: +### 1. Быстрая настройка основных параметров + +Параметры для конфигурирования: +1. явное указание платформы +2. явное указание устройтсва +3. выбрать количество очередей +4. уменьшить количество отладочной информации до минимума: оставить только критические ошибки +5. выбор аллокатора + +### 2. Замер и сравнение производительности вычислений на разных GPU +Цель пользователя: +1. Минимизация шума при измерениях +2. Воспроизводимость результатов +3. Сравнение разных конфигураций + +Параметры для конфигурирования: +1. явное указание платформы +2. явное указание устройтсва +3. выбрать количество очередей +4. **увеличить количество отладочной информации** +5. выбор аллокатора +6. Wave size override +7. Work-group size +8. профайлинг очередей `CL_QUEUE_PROFILING_ENABLE` +9. сбор статистики и уменьшение шума `CLCounterPool`** + +### 3. Отладка алгоритма GPU +Цель пользователя: +1. верификация корректности работы на разных устройствах +2. воспроизводимость ошибок + +Параметры для конфигурирования: + +### 4. Тестирование GPU +Параметры для конфигурации: + +### 5. Пользователь знает, что некоторые вычисления лучше считаются на GPU +Параметры для конфигурации: + +### 6. Задачи, требующие воспроизводимости +Параметры для конфигурации: + + + + +# Сценарии использования spla: +**Что важно всем:** возможность выбрать платформу и устройство +**Цель:** 1. Пользователь хочет решить свою задачу - Неподготовленный пользователь - важно: From af09acdead6c9dc83f2004bb8960ad2232dd74dd Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Tue, 19 May 2026 05:42:31 +0300 Subject: [PATCH 15/25] added 1 question about errors --- src/opencl/Compare.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index 4baf8f051..c9c63b8d3 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -168,6 +168,8 @@ пользовательское количество потоков work group size \ способ аллокации памяти и размер аллокатора +Иерархия ошибок? + ### Настройка очередей команд ### Логирование From 627b027af87e7f87f81dcf13dba0842230827f0c Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Mon, 1 Jun 2026 09:11:02 +0300 Subject: [PATCH 16/25] added new scenaries --- src/opencl/Compare.md | 187 +++++++++++++----------------------------- 1 file changed, 55 insertions(+), 132 deletions(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index c9c63b8d3..acf2feed9 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -121,165 +121,88 @@ По результатам сравнения, вероятно, лучшим вариантом будет использование `CLI11` и `nlohmann/json`, так как они, в отличие от `Boost.program_options`, не требуют зависимостей и являются header-only. # Сценарии использования spla: -## Дефолтный сценарий - -Дефолтный сценарий должен решать главную задачу библиотеки: ускорение вычислений. - -### Выбор платформы и устройства - -Сначала следует выбрать наиболее подходящий девайс. Для этого необходимо пройти по всем платформам, собрать все устройства каждой платформы и среди них выбрать лучший. - -Выбранное устройство должно удовлетворять следующим критериям: -1. физически существовать у пользователя - -2. проходить базовые проверки: \ - - запрос размера глобальной памяти \ - - попытка выделить и освободить буфер - -Из всех рабочих и доступных устройств необходимо выбрать наиболее быстрое. Выбор осуществляется по следующей иерархии: - -1. Внешняя GPU (eGPU) - -2. Дискретная GPU (dGPU) - -3. Интегрированная GPU (iGPU) - -4. Запуск на CPU (при отсутствии GPU) - -При наличии нескольких GPU одного типа на каждом из них запускаются микробенчмарки с эталонной задачей, характерной для SPLA. В итоге выбирается GPU, показавшая лучшие результаты, и соответствующая ей платформа. - -Данный подход решает потенциальную проблему, когда девайс указан в OpenCL-платформе, но фактически отсутствует в системе. - --- - -Нужно ли как-то учитывать параметры платформ? - -Логирование: Выдавать всю информацию (какие стандарты логирования? какая иерархия ошибок?) - -Бенчмарки: \ -Какую задачу прогонять? \ -Как вести замеры? \ -Подбор колтчества очередей: k = (t_вычислений)/ t_общ \ -если k = 0.5 => 1 очередь \ -если k >> 0.5 => ускорять передачу данных? \ -еслм k << 0. => ускорять вычисления? - -как подбирать оптимально \ -пользовательское количество потоков work group size \ -способ аллокации памяти и размер аллокатора - -Иерархия ошибок? - -### Настройка очередей команд - -### Логирование - -### Тестовые бенчмарки - +Библиотека SPLA требует явного конфигурирования. \ +При установке поставляется дефолтный конфиг. Для запуска программы пользователь должен передать библиотеке путь к конфигу (дефолтному или своему) и опционально — идентификатор конфигурации. Если идентификатор не указан, используется конфигурация default. Без конфига библиотека не запускается. ## Пользователь, который хочет решить свою задачу, используя spla: ### 1. Быстрая настройка основных параметров Параметры для конфигурирования: -1. явное указание платформы -2. явное указание устройтсва -3. выбрать количество очередей +1. явное указание платформы `SPLA_OPENCL_PLATFORM` +2. явное указание устройтсва `SPLA_OPENCL_DEVICE` +3. выбрать количество очередей `queues_count` 4. уменьшить количество отладочной информации до минимума: оставить только критические ошибки -5. выбор аллокатора ### 2. Замер и сравнение производительности вычислений на разных GPU -Цель пользователя: -1. Минимизация шума при измерениях -2. Воспроизводимость результатов -3. Сравнение разных конфигураций +Цель пользователя: Сравнение производительности разных девайсов Параметры для конфигурирования: 1. явное указание платформы 2. явное указание устройтсва 3. выбрать количество очередей -4. **увеличить количество отладочной информации** -5. выбор аллокатора -6. Wave size override -7. Work-group size +4. увеличить количество отладочной информации +5. выбор аллокатора `allocator_type` +6. размер для линейного аллокатора `linear_allocator_size` или `block_size` и `block_count` для pool аллокатора +6. `default_wgs` +7. `wave_size` 8. профайлинг очередей `CL_QUEUE_PROFILING_ENABLE` -9. сбор статистики и уменьшение шума `CLCounterPool`** +9. сбор статистики ### 3. Отладка алгоритма GPU Цель пользователя: 1. верификация корректности работы на разных устройствах -2. воспроизводимость ошибок +2. поиск ошибок в алгоритме Параметры для конфигурирования: +1. явное указание платформы +2. явное указание устройтсва +3. выбрать количество очередей +4. увеличить количество отладочной информации +5. очищать кэш при запуске +6. отключение оптимизации при компиляции + ### 4. Тестирование GPU -Параметры для конфигурации: +Цель пользователя: +1. верификация корректности работы устройства +2. поиск ошибок в устройтсве -### 5. Пользователь знает, что некоторые вычисления лучше считаются на GPU Параметры для конфигурации: +1. явное указание платформы +2. явное указание устройтсва +3. выбрать количество очередей +4. увеличить количество отладочной информации -### 6. Задачи, требующие воспроизводимости -Параметры для конфигурации: - +## Разработчик spla: -# Сценарии использования spla: -**Что важно всем:** возможность выбрать платформу и устройство -**Цель:** -1. Пользователь хочет решить свою задачу - - Неподготовленный пользователь - - важно: - - быстрая настройка через флаги - - что конфигурировать: - - уменьшить количество отладочной информации - - остальное - дефолтные параметры - - Опытный пользователь: - - важно: - - детальная ручная конфигурация параметров через конфигурационный файл - - ускорение вычислений с разреженными данными - - что конфигурировать: - - управление кэшем - - кастомные аллокаторы для разных форматов данных - - управление очередями команд - - Wave size override - - Work-group size - - оптимизация доступа к глобальной памяти - - управление логированием -2. Разработчик spla - - Отладчик, тестировик - - важно: - - верификация корректности работы на разных устройствах - - воспроизводимость ошибок - - что конфигурировать: - - возможность работать только на 1 гпу - - подробное логирование - - отключение кэша для принудительной перекомпиляции - - тестирование на неподдерживаемых вендорах без падения с ошибкой - - Бенчмаркер - - важно: - - минимизация шума при измерениях - - воспроизводимость результатов - - сравнение разных конфигураций - - что конфигурировать: - - профайлинг очередей `CL_QUEUE_PROFILING_ENABLE` - - сбор статистики и уменьшение шума `CLCounterPool` - - количество очередей для измерения параллелизма - - линейный аллокатор для предсказуемости памяти - - Wave size override - - Work-group size - - оптимизация доступа к глобальной памяти - - Расширяющий функциональность - - важно: - - возможность встроить код в существующую инфраструктуру - - чтобы новый код работал на всех устройтсвах - - что конфигурировать: - - включение кэша - - кастомные аллокаторы для разных форматов данных - - управление очередями - - Wave size override - - Work-group size - -# Что нужно конфигурировать +### 1. Бенчмаркер + +Цели и параметры конфигурирования аналогичны [сценарию 2](#2-замер-и-сравнение-производительности-вычислений-на-разных-gpu) + + +### 2. Отладчик, тестировик + +Цели и параметры конфигурирования аналогичны [сценарию 3](#3-отладка-алгоритма-gpu) + + + +## Основные дефолтные значения + +платформа: первая платформа \ +девайс: первое устройство \ +queues_count = 1 \ +отладочная информация: критичнеские ошибки \ +аллокатор: general \ +default_wgs: 1\ +wave_size: 1\ +профайлинг: false +сбор статистики: false +очищать кэш при запуске: false +отключение оптимизации при компиляции: false + + # Структура конфига (JSON) From c1b7f2d7be1eec461b5c0de57d7574758a038590 Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Thu, 9 Jul 2026 23:04:18 +0500 Subject: [PATCH 17/25] added manual --- src/opencl/Compare.md | 395 ++++++++++++++++++++++++++---------------- 1 file changed, 246 insertions(+), 149 deletions(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index acf2feed9..1d51c5016 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -120,156 +120,253 @@ ## Итог: По результатам сравнения, вероятно, лучшим вариантом будет использование `CLI11` и `nlohmann/json`, так как они, в отличие от `Boost.program_options`, не требуют зависимостей и являются header-only. -# Сценарии использования spla: -Библиотека SPLA требует явного конфигурирования. \ -При установке поставляется дефолтный конфиг. Для запуска программы пользователь должен передать библиотеке путь к конфигу (дефолтному или своему) и опционально — идентификатор конфигурации. Если идентификатор не указан, используется конфигурация default. Без конфига библиотека не запускается. - -## Пользователь, который хочет решить свою задачу, используя spla: -### 1. Быстрая настройка основных параметров - -Параметры для конфигурирования: -1. явное указание платформы `SPLA_OPENCL_PLATFORM` -2. явное указание устройтсва `SPLA_OPENCL_DEVICE` -3. выбрать количество очередей `queues_count` -4. уменьшить количество отладочной информации до минимума: оставить только критические ошибки - -### 2. Замер и сравнение производительности вычислений на разных GPU -Цель пользователя: Сравнение производительности разных девайсов - -Параметры для конфигурирования: -1. явное указание платформы -2. явное указание устройтсва -3. выбрать количество очередей -4. увеличить количество отладочной информации -5. выбор аллокатора `allocator_type` -6. размер для линейного аллокатора `linear_allocator_size` или `block_size` и `block_count` для pool аллокатора -6. `default_wgs` -7. `wave_size` -8. профайлинг очередей `CL_QUEUE_PROFILING_ENABLE` -9. сбор статистики - -### 3. Отладка алгоритма GPU -Цель пользователя: -1. верификация корректности работы на разных устройствах -2. поиск ошибок в алгоритме - -Параметры для конфигурирования: -1. явное указание платформы -2. явное указание устройтсва -3. выбрать количество очередей -4. увеличить количество отладочной информации -5. очищать кэш при запуске -6. отключение оптимизации при компиляции - - -### 4. Тестирование GPU -Цель пользователя: -1. верификация корректности работы устройства -2. поиск ошибок в устройтсве - -Параметры для конфигурации: -1. явное указание платформы -2. явное указание устройтсва -3. выбрать количество очередей -4. увеличить количество отладочной информации - - - -## Разработчик spla: - -### 1. Бенчмаркер - -Цели и параметры конфигурирования аналогичны [сценарию 2](#2-замер-и-сравнение-производительности-вычислений-на-разных-gpu) - - -### 2. Отладчик, тестировик - -Цели и параметры конфигурирования аналогичны [сценарию 3](#3-отладка-алгоритма-gpu) - - - -## Основные дефолтные значения - -платформа: первая платформа \ -девайс: первое устройство \ -queues_count = 1 \ -отладочная информация: критичнеские ошибки \ -аллокатор: general \ -default_wgs: 1\ -wave_size: 1\ -профайлинг: false -сбор статистики: false -очищать кэш при запуске: false -отключение оптимизации при компиляции: false - - - -# Структура конфига (JSON) + +# Механизм конфигурирования библиотеки SPLA + +## МАНУАЛ: + +## НАЗВАНИЕ +spla - это фреймворк для математических вычислений с использованием GPU/ускорения + +## СИНОПСИС + +```cpp +#include + + +int main(int argc, char* argv[]) { + + spla_configure(argc, argv); + + return 0; +} +``` +Функция `spla_configure(argc, argv)` необходима для обработки аргументов командной строки, переменных окружения и конфигурационных файлов. + +(будет написана) + +## ОПИСАНИЕ +**spla** - это библиотека с открытым исходным кодом, предоставляющая примитивы разреженной линейной алгебры (матрицы, векторы, скаляры) для математических вычислений с ускорением на GPU. Библиотека поддерживает широкий спектр операций, включая умножение матрицы на вектор, решение систем линейных уравнений и другие алгоритмы разреженной алгебры. + +Для большинства пользователей важно, на каком ускорителе будет запускаться их проект, поэтому необходима возможность явного указания графического ускорителя, OpenCL платформы, количества очередей команд и других параметров, влияющих на производительность и удобство пользователя. + +Библиотека предоставляет механизмы конфигурирования, показанные в порядке убывания приоритета. + +1. Аргументы командной строки 1. +2. Переменные окружения 2. +3. Пользовательский конфигурационный TOML/INI файл 3. +4. Системный конфигурационный TOML/INI файл 3. + +Системный конфигурационный файл имеет наименьший приоритет. \ +Его настройки переопределяются пользовательским конфигурационным файлом, переменными окружения и аргументами командной строки. + +Пользовательский конфигурационный файл имеет приоритет над системным +конфигурационным файлом. \ +Его настройки переопределяются переменными +окружения и аргументами командной строки. + +Переменные окружения имеют приоритет над системным и пользовательским конфигурационными файлами, но уступают аргументам командной строки. + +Аргументы командной строки имеют наивысший приоритет и переопределяют любые настройки, определенные предыдущими способами. + +Если источника конфигурации с меньшим приоритетом не существует, библиотека игнорирует его и переходит к следующему источнику конфигурации. + +Библиотека требует настройки всех обязательных параметров. Без этого будет генерироваться исключение `IncompleteConfigError`.\ +Чтобы исключение не возникало, пользователь должен явно настроить все параметры любым [способом](#configuration_methods). + +> 1 Описание аргументов командной строки приведены в разделе [ПАРАМЕТРЫ КОМАНДНОЙ СТРОКИ](#options). \ +2 Описание переменнных окружения приведены в разделе [ПЕРЕМЕННЫЕ ОКРУЖЕНИЯ](#env_variables). \ +3 Шаблон конфигурационного файла с описанием приведен [здесь](#config). + +## ПАРАМЕТРЫ КОМАНДНОЙ СТРОКИ +```bash +-sh +--spla-help +``` +Выводит список всех доступных флагов spla с кратким описанием. + +```bash +-sv +--spla-version +``` +Показывает номер версии spla. + +```bash +-ss <путь> +--spla-sconf <путь> +``` +Путь к системному конфигурационному файлу. + +По умолчанию ищет файл в стандартном для данной ОС месте.\ +`/etc/spla/spla.toml` на Linux. \ +`/Library/Preferences/spla/spla.toml` на macOS. \ +`%ProgramData%\spla\spla.toml` на Windows. + +```bash +-su <путь> +--spla-uconf <путь> +``` +Путь к пользовательскому конфигурационному файлу. + +По умолчанию ищет файл в стандартном для данной ОС месте. \ +`~/.config/spla/spla.toml` на Linux. \ +`~/Library/Application Support/spla/spla.toml` на macOS. \ +`%APPDATA%\spla\spla.toml` на Windows. ```bash -config: - - "platform": - "selection": - "user_alias": string - "official_name": string - "vendor": "nvidia" | "amd" | "intel" | "img" | "" - "index": int - "priority": int - "fallback": (???) # Нужен ли fallback - "device": - "selection": - "user_alias": string - "official_name": string - "type": "gpu" | "cpu" - "index": int - "priority": int - "naming": - "accelerator_name" # m_name - "cache_suffix" # m_suffix - "tuning": - "default_work_group_size": int # m_default_wgs - "wave_size": int # m_wave_size - "memory_banks": int # m_num_of_mem_banks - "memory_alignment": int # m_addr_align - "fallback": (???) # Нужен ли fallback - "performance" - "memory" - "linear_allocator_size_mb": int # DEFAULT_SIZE - "allocator_strategy": "auto" | "linear" | "general" | "vendor" - "vendor_strategy": - "nvidia": "linear" | "general" - "amd": "linear" | "general" - "intel": "linear" | "general" - "img": "linear" | "general" - "queues": - "count": int - +-sp <индекс> +--spla-platform <индекс> +``` +Индекс OpenCL платформы. + +```bash +-sd <индекс> +--spla-device <индекс> +``` +Индекс OpenCL-устройства выбранной платформы (GPU/CPU). + +```bash +-sq <число> +--spla-queues <число> +``` +Количество очередей команд. + +Увеличение числа очередей может повысить производительность +за счет параллельного выполнения независимых задач, но слишком большое значение может снизить производительность из-за накладных расходов. \ +Рекомендуется начинать с 1 и экспериментально подбирать оптимальное значение. + +```bash +-sV <уровень> +--spla-verbosity <уровень> +``` +Уровень детализации отладочной информации, выводимой библиотекой. + +| Уровень | Значение | Описание | +|:-------:|:---------|:---------| +| **0** | OFF | Вывод отключён. Сообщения не выводятся. | +| **1** | ERROR | Только критические ошибки. | +| **2** | WARNING | Ошибки и предупреждения. | +| **3** | INFO | Основные этапы работы библиотеки. | + +Что выводится на каждом уровне: + +1. ERROR — `Error`, `NoAcceleration`, `PlatformNotFound`, `DeviceNotFound`, `InvalidState`, `InvalidArgument`, `CompilationError` + +2. WARNING — добавляет к ERROR: `NoValue`, `NotImplemented` + +3. INFO — добавляет к WARNING: `Ok` - информация об инициализации, выборе платформы/устройства, загрузке конфигурации + +```bash +-sp +--spla-profiling +``` +Профилирование очередей команд OpenCL. + +Bключение профилирования добавляет накладные расходы на каждую +операцию и может замедлить выполнение. + +```bash +-sa <тип> +--spla-allocator <тип> +``` +Тип аллокатора памяти для OpenCL-устройства. \ +Ожидает: lineral | general. + +Выбор аллокатора влияет на производительность операций с памятью. +Линейный аллокатор даёт прирост скорости за счёт последовательного выделения, +но может привести к фрагментации памяти при длительной работе. +Общий аллокатор более надёжен, но медленнее. + +```bash +-sS <размер> +--spla-allocator-size <размер> +``` +Размер линейного аллокатора в байтах. + +Увеличение размера позволяет выделять больше памяти за один раз, но увеличивает потребление ресурсов. \ +Этот параметр необходим только при использовании линейного аллокатора `--spla-allocator linear`. +При использовании общего аллокатора можно не указывать. + +Пример: +```bash +./my_program --spla-uconf ~/my_configs/spla.toml --spla-platform 1 -sd 0 --spla-verbosity 3 -sp true --spla-allocator linear --spla-allocator-size 1048576 +``` + +## ПЕРЕМЕННЫЕ ОКРУЖЕНИЯ +Для всех параметров командной строки (кроме --spla-help, --spla-version) существуют аналоги в виде переменных окружения. + +`SPLA_SYSTEM_CONFIG_PATH` \ +Путь к системному конфигурационному файлу. Аналог параметра --spla-sconf. + +`SPLA_USER_CONFIG_PATH` \ +Путь к пользовательскому конфигурационному файлу. Аналог параметра --spla-uconf. + +`SPLA_OPENCL_PLATFORM` \ +Индекс OpenCL платформы. Аналог параметра --spla-platform. + +`SPLA_OPENCL_DEVICE`\ +Индекс OpenCL-устройства на выбранной платформе. +Аналог параметра --spla-device. + +`SPLA_QUEUES`\ +Количество очередей команд OpenCL. +Аналог параметра --spla-queues. + +`SPLA_VERBOSITY`\ +Уровень детализации отладочной информации. +Аналог параметра --spla-verbosity.\ +Принимает значения от 0 до 3. + +`SPLA_PROFILING`\ +Включает профилирование очередей команд OpenCL. +Аналог параметра --spla-profiling. + +`SPLA_ALLOCATOR`\ +Тип аллокатора памяти для OpenCL-устройства. +Аналог параметра --spla-allocator.\ +Принимает значения: linear, general. + +`SPLA_ALLOCATOR_SIZE`\ +Размер линейного аллокатора в байтах. +Аналог параметра --spla-allocator-size.\ +Имеет смысл только при использовании линейного аллокатора. + + +## КОНФИГУРАЦИОННЫЕ ФАЙЛЫ +Для всех аргументов командной строки (кроме --spla-help, --spla-version, --spla-sconf, --spla-uconf) и всех переменных окружения существуют аналоги в виде параметров конфигурационного файла. + +Формат файла - TOML или INI. + +Типы значений. +1. platform = int +2. device = int +3. queues = int +4. verbosity = int +5. profiling = true | false +6. allocator = linear | general +7. allocator_size = int + +Примеры конфигурационных файлов.\ +Этот формат справедлив как для пользовательского, так и для системного конфигурационного файла. + +Формат INI. +```toml +platform = 1 +device = 0 +queues = 4 +verbosity = 2 +profiling = false +allocator = "linear" +allocator_size = 1048576 ``` +Формата ini. +```ini +platform = 1 +device = 0 +queues = 4 +verbosity = 2 +profiling = true +allocator = linear +allocator_size = 1048576 +``` \ No newline at end of file From 8c9ddff705025c412311a609cdd051ba01a2c542 Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Fri, 10 Jul 2026 11:07:51 +0500 Subject: [PATCH 18/25] Fixed the incorrect format name in 1 example in CONFIGURATION FALE section (INI -> TOML) --- src/opencl/Compare.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/opencl/Compare.md b/src/opencl/Compare.md index 1d51c5016..6df361e57 100644 --- a/src/opencl/Compare.md +++ b/src/opencl/Compare.md @@ -349,7 +349,7 @@ Bключение профилирования добавляет накладн Примеры конфигурационных файлов.\ Этот формат справедлив как для пользовательского, так и для системного конфигурационного файла. -Формат INI. +Формат TOML. ```toml platform = 1 device = 0 @@ -360,7 +360,7 @@ allocator = "linear" allocator_size = 1048576 ``` -Формата ini. +Формата INI. ```ini platform = 1 device = 0 From c90f1857e2062bb0be29cefcc3b46658ddf49ef8 Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Sun, 26 Jul 2026 23:03:19 +0500 Subject: [PATCH 19/25] add parsers --- src/opencl/cl_configure.cpp | 301 ++++++++++++++++++++++++++++++++++++ src/opencl/cl_configure.hpp | 65 ++++++++ 2 files changed, 366 insertions(+) create mode 100644 src/opencl/cl_configure.cpp create mode 100644 src/opencl/cl_configure.hpp diff --git a/src/opencl/cl_configure.cpp b/src/opencl/cl_configure.cpp new file mode 100644 index 000000000..a4c84e5de --- /dev/null +++ b/src/opencl/cl_configure.cpp @@ -0,0 +1,301 @@ +#include "cl_configure.hpp" + +namespace spla { + + Config config_user_and_system; + Config config_cli_and_env; + Config config_final; + + void Config::merge(const Config& source) { + if (source.platform.has_value()) platform = source.platform; + if (source.device.has_value()) device = source.device; + if (source.queues.has_value()) queues = source.queues; + if (source.verbosity.has_value()) verbosity = source.verbosity; + if (source.allocator.has_value()) allocator = source.allocator; + if (source.allocator_size.has_value()) allocator_size = source.allocator_size; + if (source.profiling.has_value()) profiling = source.profiling; + if (source.system_config_path.has_value()) system_config_path = source.system_config_path; + if (source.user_config_path.has_value()) user_config_path = source.user_config_path; + if (source.help.has_value()) help = source.help; + if (source.version.has_value()) version = source.version; + } + + void Config::reset() { + *this = Config{}; + } + + bool Config::has_all_required() const { + return platform.has_value() && + device.has_value() && + queues.has_value() && + profiling.has_value() && + allocator.has_value() && + allocator_size.has_value() && + verbosity.has_value(); + } + + std::string get_spla_version() { + return "SPLA version: 0.0.0"; + } + + std::string get_home_directory() { + #ifdef _WIN32 + const char* home = std::getenv("USERPROFILE"); + if (home) return std::string(home); + + const char* drive = std::getenv("HOMEDRIVE"); + const char* path = std::getenv("HOMEPATH"); + if (drive && path) return std::string(drive) + std::string(path); + return ""; + + #elif defined(__APPLE__) || defined(__linux__) || defined(__unix__) + const char* home = std::getenv("HOME"); + if (home) return std::string(home); + + struct passwd* pw = getpwuid(getuid()); + if (pw) return std::string(pw->pw_dir); + return ""; + + #else + #error "Unsupported operating system" + #endif + } + + std::string get_default_system_config_path() { + #ifdef _WIN32 + const char* program_data = std::getenv("PROGRAMDATA"); + if (program_data) { + return std::string(program_data) + "\\spla\\"; + } + return "C:\\ProgramData\\spla\\"; + + #elif defined(__APPLE__) + return "/Library/Application Support/spla/"; + + #elif defined(__linux__) || defined(__unix__) + return "/etc/spla/"; + + #else + #error "Unsupported operating system" + #endif + } + + std::string get_default_user_config_path() { + std::string home = get_home_directory(); + if (home.empty()) { + return ""; + } + + #ifdef _WIN32 + const char* app_data = std::getenv("APPDATA"); + if (app_data) return std::string(app_data) + "\\spla\\"; + return home + "\\AppData\\Roaming\\spla\\"; + + #elif defined(__APPLE__) + return home + "/Library/Application Support/spla/"; + + #elif defined(__linux__) || defined(__unix__) + return home + "/.config/spla/"; + + #else + #error "Unsupported operating system" + #endif + } + + std::string find_first_json_file(const std::string& directory) { + if (directory.empty() || !std::filesystem::exists(directory)) { + return ""; + } + + for (const auto& entry : std::filesystem::directory_iterator(directory)) { + if (entry.is_regular_file()) { + std::string path = entry.path().string(); + if (path.size() >= 5 && + path.compare(path.size() - 5, 5, ".json") == 0) { + return path; + } + } + } + return ""; + } + + ConfigStatus load_from_file(const std::string& path) { + try { + std::ifstream file(path); + if (!file.is_open()) { + std::cerr << "Failed to open file: " << path << std::endl; + return ConfigStatus::FileError; + } + + nlohmann::json config_data = nlohmann::json::parse(file); + + if (config_data.contains("platform")) { + config_user_and_system.platform = config_data["platform"].get(); + } + if (config_data.contains("device")) { + config_user_and_system.device = config_data["device"].get(); + } + if (config_data.contains("queues")) { + config_user_and_system.queues = config_data["queues"].get(); + } + if (config_data.contains("verbosity")) { + config_user_and_system.verbosity = config_data["verbosity"].get(); + } + if (config_data.contains("profiling")) { + config_user_and_system.profiling = config_data["profiling"].get(); + } + if (config_data.contains("allocator")) { + config_user_and_system.allocator = config_data["allocator"].get(); + } + if (config_data.contains("allocator_size")) { + config_user_and_system.allocator_size = config_data["allocator_size"].get(); + } + + return ConfigStatus::Ok; + + } catch (const nlohmann::json::exception& e) { + std::cerr << "Error parsing JSON file '" << path << "': " << e.what() << std::endl; + return ConfigStatus::UserOrSystemConfParseError; + } + } + + ConfigStatus parse_system_and_user_conf() { + std::string sys_dir = config_cli_and_env.system_config_path.value_or(get_default_system_config_path()); + std::string user_dir = config_cli_and_env.user_config_path.value_or(get_default_user_config_path()); + + bool file_loaded = false; + + if (sys_dir != "") { + std::string sys_file = find_first_json_file(sys_dir); + if (sys_file != "") { + std::cout << "Loading system config: " << sys_file << std::endl; + load_from_file(sys_file); + file_loaded = true; + } + } + + if (user_dir != "") { + std::string user_file = find_first_json_file(user_dir); + if (user_file != "") { + std::cout << "Loading user config: " << user_file << std::endl; + load_from_file(user_file); + file_loaded = true; + } + } + + if (!file_loaded) { + std::cerr << "Warning: No JSON configuration files found." << std::endl; + } + + return ConfigStatus::Ok; + } + + ConfigStatus parse_cli_and_env(int argc, char** argv) { + CLI::App app{"SPLA configuration"}; + + app.add_flag("-sh,--spla-help", config_cli_and_env.help, "Show help and exit"); + app.add_flag("-sv,--spla-version", config_cli_and_env.version, "Show version and exit"); + + app.add_option("-ss,--spla-sconf", config_cli_and_env.system_config_path, "Path to system configuration file") + ->envname("SPLA_SYSTEM_CONFIG_PATH"); + + app.add_option("-su,--spla-uconf", config_cli_and_env.user_config_path, "Path to user configuration file") + ->envname("SPLA_USER_CONFIG_PATH"); + + app.add_option("-sp,--spla-platform", config_cli_and_env.platform, "OpenCL platform index") + ->envname("SPLA_OPENCL_PLATFORM") + ->check(CLI::PositiveNumber); + + app.add_option("-sd,--spla-device", config_cli_and_env.device, "OpenCL device index") + ->envname("SPLA_OPENCL_DEVICE") + ->check(CLI::PositiveNumber); + + app.add_option("-sq,--spla-queues", config_cli_and_env.queues, "Number of command queues") + ->envname("SPLA_QUEUES") + ->check(CLI::PositiveNumber); + + app.add_flag("-pr,--spla-profiling", config_cli_and_env.profiling, "Enable profiling of command queues") + ->envname("SPLA_PROFILING"); + + app.add_option("-sa,--spla-allocator", config_cli_and_env.allocator, "Allocator type: linear or general") + ->envname("SPLA_ALLOCATOR") + ->check(CLI::IsMember({"linear", "general"})); + + app.add_option("-sS,--spla-allocator-size", config_cli_and_env.allocator_size, "Linear allocator size in bytes") + ->envname("SPLA_ALLOCATOR_SIZE") + ->check(CLI::PositiveNumber); + + app.add_option("-sV,--spla-verbosity", config_cli_and_env.verbosity, "Verbosity level (0-3)") + ->envname("SPLA_VERBOSITY") + ->check(CLI::Range(0, 3)); + + try { + app.parse(argc, argv); + } catch (const CLI::ParseError& e) { + app.exit(e); + return ConfigStatus::CliOrEnvParseError; + } + + if (config_cli_and_env.help) { + std::cout << app.help() << std::endl; + return ConfigStatus::HelpRequested; + } + + if (config_cli_and_env.version) { + std::cout << get_spla_version() << std::endl; + return ConfigStatus::VersionRequested; + } + + return ConfigStatus::Ok; + } + + ConfigStatus validate(){ + + if (!config_final.has_all_required()) { + std::cerr << "Error: Missing required configuration parameters" << std::endl; + std::exit(1); + } + + return ConfigStatus::Ok; + } + + ConfigStatus apply(){ + return ConfigStatus::Ok; + } + + ConfigStatus configure(int argc, char** argv) { + config_user_and_system.reset(); + config_cli_and_env.reset(); + config_final.reset(); + + ConfigStatus status = parse_cli_and_env(argc, argv); + + if (status == ConfigStatus::HelpRequested || status == ConfigStatus::VersionRequested) { + return status; + } + + if (status != ConfigStatus::Ok) { + return status; + } + + status = parse_system_and_user_conf(); + if (status != ConfigStatus::Ok) { + return status; + } + + config_final = config_user_and_system; + config_final.merge(config_cli_and_env); + + status = validate(); + if (status != ConfigStatus::Ok) { + return status; + } + + status = apply(); + if (status != ConfigStatus::Ok) { + return status; + } + + return ConfigStatus::Ok; + } +} \ No newline at end of file diff --git a/src/opencl/cl_configure.hpp b/src/opencl/cl_configure.hpp new file mode 100644 index 000000000..7e25a7bb2 --- /dev/null +++ b/src/opencl/cl_configure.hpp @@ -0,0 +1,65 @@ +#pragma once + +#include +#include + +#include "CLI/CLI.hpp" +#include + +#ifdef _WIN32 +#elif defined(__APPLE__) || defined(__linux__) || defined(__unix__) + #include + #include +#endif + +namespace spla { + + struct Config { + std::optional help; + std::optional version; + std::optional system_config_path; + std::optional user_config_path; + std::optional platform; + std::optional device; + std::optional queues; + std::optional profiling; + std::optional allocator; + std::optional allocator_size; + std::optional verbosity; + + void merge(const Config& source); + void reset(); + bool has_all_required() const; + }; + + enum ConfigStatus { + Ok, + HelpRequested, + VersionRequested, + + CliOrEnvParseError, + UserOrSystemConfParseError, + FileError + }; + + std::string get_spla_version(); + + std::string get_home_directory(); + std::string get_default_system_config_path(); + std::string get_default_user_config_path(); + std::string find_first_json_file(const std::string& directory); + ConfigStatus load_from_file(const std::string& path); + + ConfigStatus parse_cli_and_env(int argc, char** argv); + ConfigStatus parse_system_and_user_conf(); + + ConfigStatus validate(); + ConfigStatus apply(); + + ConfigStatus configure(int argc, char** argv); + + extern Config config_user_and_system; + extern Config config_cli_and_env; + extern Config config_final; + +} \ No newline at end of file From 82028eb48a27de0a3c9f39ee158bd6f12712ce98 Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Sun, 26 Jul 2026 23:15:57 +0500 Subject: [PATCH 20/25] fixed formatting errors --- src/opencl/cl_configure.cpp | 92 ++++++++++++++++++------------------- src/opencl/cl_configure.hpp | 31 ++++++------- 2 files changed, 61 insertions(+), 62 deletions(-) diff --git a/src/opencl/cl_configure.cpp b/src/opencl/cl_configure.cpp index a4c84e5de..1e7368aac 100644 --- a/src/opencl/cl_configure.cpp +++ b/src/opencl/cl_configure.cpp @@ -39,16 +39,16 @@ namespace spla { } std::string get_home_directory() { - #ifdef _WIN32 +#ifdef _WIN32 const char* home = std::getenv("USERPROFILE"); if (home) return std::string(home); const char* drive = std::getenv("HOMEDRIVE"); - const char* path = std::getenv("HOMEPATH"); + const char* path = std::getenv("HOMEPATH"); if (drive && path) return std::string(drive) + std::string(path); return ""; - #elif defined(__APPLE__) || defined(__linux__) || defined(__unix__) +#elif defined(__APPLE__) || defined(__linux__) || defined(__unix__) const char* home = std::getenv("HOME"); if (home) return std::string(home); @@ -56,28 +56,28 @@ namespace spla { if (pw) return std::string(pw->pw_dir); return ""; - #else - #error "Unsupported operating system" - #endif +#else + #error "Unsupported operating system" +#endif } std::string get_default_system_config_path() { - #ifdef _WIN32 - const char* program_data = std::getenv("PROGRAMDATA"); - if (program_data) { - return std::string(program_data) + "\\spla\\"; - } - return "C:\\ProgramData\\spla\\"; +#ifdef _WIN32 + const char* program_data = std::getenv("PROGRAMDATA"); + if (program_data) { + return std::string(program_data) + "\\spla\\"; + } + return "C:\\ProgramData\\spla\\"; - #elif defined(__APPLE__) - return "/Library/Application Support/spla/"; +#elif defined(__APPLE__) + return "/Library/Application Support/spla/"; - #elif defined(__linux__) || defined(__unix__) - return "/etc/spla/"; +#elif defined(__linux__) || defined(__unix__) + return "/etc/spla/"; - #else - #error "Unsupported operating system" - #endif +#else + #error "Unsupported operating system" +#endif } std::string get_default_user_config_path() { @@ -86,20 +86,20 @@ namespace spla { return ""; } - #ifdef _WIN32 +#ifdef _WIN32 const char* app_data = std::getenv("APPDATA"); if (app_data) return std::string(app_data) + "\\spla\\"; return home + "\\AppData\\Roaming\\spla\\"; - #elif defined(__APPLE__) +#elif defined(__APPLE__) return home + "/Library/Application Support/spla/"; - #elif defined(__linux__) || defined(__unix__) +#elif defined(__linux__) || defined(__unix__) return home + "/.config/spla/"; - #else - #error "Unsupported operating system" - #endif +#else + #error "Unsupported operating system" +#endif } std::string find_first_json_file(const std::string& directory) { @@ -160,7 +160,7 @@ namespace spla { } ConfigStatus parse_system_and_user_conf() { - std::string sys_dir = config_cli_and_env.system_config_path.value_or(get_default_system_config_path()); + std::string sys_dir = config_cli_and_env.system_config_path.value_or(get_default_system_config_path()); std::string user_dir = config_cli_and_env.user_config_path.value_or(get_default_user_config_path()); bool file_loaded = false; @@ -197,37 +197,37 @@ namespace spla { app.add_flag("-sv,--spla-version", config_cli_and_env.version, "Show version and exit"); app.add_option("-ss,--spla-sconf", config_cli_and_env.system_config_path, "Path to system configuration file") - ->envname("SPLA_SYSTEM_CONFIG_PATH"); + ->envname("SPLA_SYSTEM_CONFIG_PATH"); app.add_option("-su,--spla-uconf", config_cli_and_env.user_config_path, "Path to user configuration file") - ->envname("SPLA_USER_CONFIG_PATH"); + ->envname("SPLA_USER_CONFIG_PATH"); app.add_option("-sp,--spla-platform", config_cli_and_env.platform, "OpenCL platform index") - ->envname("SPLA_OPENCL_PLATFORM") - ->check(CLI::PositiveNumber); + ->envname("SPLA_OPENCL_PLATFORM") + ->check(CLI::PositiveNumber); app.add_option("-sd,--spla-device", config_cli_and_env.device, "OpenCL device index") - ->envname("SPLA_OPENCL_DEVICE") - ->check(CLI::PositiveNumber); + ->envname("SPLA_OPENCL_DEVICE") + ->check(CLI::PositiveNumber); app.add_option("-sq,--spla-queues", config_cli_and_env.queues, "Number of command queues") - ->envname("SPLA_QUEUES") - ->check(CLI::PositiveNumber); + ->envname("SPLA_QUEUES") + ->check(CLI::PositiveNumber); app.add_flag("-pr,--spla-profiling", config_cli_and_env.profiling, "Enable profiling of command queues") - ->envname("SPLA_PROFILING"); + ->envname("SPLA_PROFILING"); app.add_option("-sa,--spla-allocator", config_cli_and_env.allocator, "Allocator type: linear or general") - ->envname("SPLA_ALLOCATOR") - ->check(CLI::IsMember({"linear", "general"})); + ->envname("SPLA_ALLOCATOR") + ->check(CLI::IsMember({"linear", "general"})); app.add_option("-sS,--spla-allocator-size", config_cli_and_env.allocator_size, "Linear allocator size in bytes") - ->envname("SPLA_ALLOCATOR_SIZE") - ->check(CLI::PositiveNumber); + ->envname("SPLA_ALLOCATOR_SIZE") + ->check(CLI::PositiveNumber); app.add_option("-sV,--spla-verbosity", config_cli_and_env.verbosity, "Verbosity level (0-3)") - ->envname("SPLA_VERBOSITY") - ->check(CLI::Range(0, 3)); + ->envname("SPLA_VERBOSITY") + ->check(CLI::Range(0, 3)); try { app.parse(argc, argv); @@ -249,7 +249,7 @@ namespace spla { return ConfigStatus::Ok; } - ConfigStatus validate(){ + ConfigStatus validate() { if (!config_final.has_all_required()) { std::cerr << "Error: Missing required configuration parameters" << std::endl; @@ -259,7 +259,7 @@ namespace spla { return ConfigStatus::Ok; } - ConfigStatus apply(){ + ConfigStatus apply() { return ConfigStatus::Ok; } @@ -269,11 +269,11 @@ namespace spla { config_final.reset(); ConfigStatus status = parse_cli_and_env(argc, argv); - + if (status == ConfigStatus::HelpRequested || status == ConfigStatus::VersionRequested) { return status; } - + if (status != ConfigStatus::Ok) { return status; } @@ -298,4 +298,4 @@ namespace spla { return ConfigStatus::Ok; } -} \ No newline at end of file +}// namespace spla \ No newline at end of file diff --git a/src/opencl/cl_configure.hpp b/src/opencl/cl_configure.hpp index 7e25a7bb2..921821f2f 100644 --- a/src/opencl/cl_configure.hpp +++ b/src/opencl/cl_configure.hpp @@ -1,31 +1,31 @@ #pragma once -#include #include +#include #include "CLI/CLI.hpp" #include #ifdef _WIN32 #elif defined(__APPLE__) || defined(__linux__) || defined(__unix__) - #include #include + #include #endif namespace spla { struct Config { - std::optional help; - std::optional version; + std::optional help; + std::optional version; std::optional system_config_path; std::optional user_config_path; - std::optional platform; - std::optional device; - std::optional queues; - std::optional profiling; + std::optional platform; + std::optional device; + std::optional queues; + std::optional profiling; std::optional allocator; - std::optional allocator_size; - std::optional verbosity; + std::optional allocator_size; + std::optional verbosity; void merge(const Config& source); void reset(); @@ -44,12 +44,11 @@ namespace spla { std::string get_spla_version(); - std::string get_home_directory(); - std::string get_default_system_config_path(); - std::string get_default_user_config_path(); - std::string find_first_json_file(const std::string& directory); + std::string get_home_directory(); + std::string get_default_system_config_path(); + std::string get_default_user_config_path(); + std::string find_first_json_file(const std::string& directory); ConfigStatus load_from_file(const std::string& path); - ConfigStatus parse_cli_and_env(int argc, char** argv); ConfigStatus parse_system_and_user_conf(); @@ -62,4 +61,4 @@ namespace spla { extern Config config_cli_and_env; extern Config config_final; -} \ No newline at end of file +}// namespace spla \ No newline at end of file From 464aaa0fa698a00f1a3673b99f85dea72c1931ae Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Tue, 28 Jul 2026 19:25:11 +0500 Subject: [PATCH 21/25] changed cli parser, file parser, made validate --- src/opencl/cl_configure.cpp | 334 ++++++++++++++++++++++++++---------- src/opencl/cl_configure.hpp | 32 ++-- 2 files changed, 259 insertions(+), 107 deletions(-) diff --git a/src/opencl/cl_configure.cpp b/src/opencl/cl_configure.cpp index 1e7368aac..a28f1de2c 100644 --- a/src/opencl/cl_configure.cpp +++ b/src/opencl/cl_configure.cpp @@ -1,4 +1,5 @@ #include "cl_configure.hpp" +#include "opencl.hpp" namespace spla { @@ -7,37 +8,23 @@ namespace spla { Config config_final; void Config::merge(const Config& source) { + if (source.system_config_path.has_value()) system_config_path = source.system_config_path; + if (source.user_config_path.has_value()) user_config_path = source.user_config_path; if (source.platform.has_value()) platform = source.platform; if (source.device.has_value()) device = source.device; if (source.queues.has_value()) queues = source.queues; - if (source.verbosity.has_value()) verbosity = source.verbosity; + if (source.profiling.has_value()) profiling = source.profiling; if (source.allocator.has_value()) allocator = source.allocator; if (source.allocator_size.has_value()) allocator_size = source.allocator_size; - if (source.profiling.has_value()) profiling = source.profiling; - if (source.system_config_path.has_value()) system_config_path = source.system_config_path; - if (source.user_config_path.has_value()) user_config_path = source.user_config_path; - if (source.help.has_value()) help = source.help; - if (source.version.has_value()) version = source.version; + if (source.default_wgs.has_value()) default_wgs = source.default_wgs; + if (source.wave_size.has_value()) wave_size = source.wave_size; + if (source.verbosity.has_value()) verbosity = source.verbosity; } void Config::reset() { *this = Config{}; } - bool Config::has_all_required() const { - return platform.has_value() && - device.has_value() && - queues.has_value() && - profiling.has_value() && - allocator.has_value() && - allocator_size.has_value() && - verbosity.has_value(); - } - - std::string get_spla_version() { - return "SPLA version: 0.0.0"; - } - std::string get_home_directory() { #ifdef _WIN32 const char* home = std::getenv("USERPROFILE"); @@ -119,129 +106,169 @@ namespace spla { return ""; } - ConfigStatus load_from_file(const std::string& path) { + ConfigStatus load_from_file(const std::string& path, Config& cfg) { try { std::ifstream file(path); if (!file.is_open()) { std::cerr << "Failed to open file: " << path << std::endl; - return ConfigStatus::FileError; + return ConfigStatus::OpenFileError; } nlohmann::json config_data = nlohmann::json::parse(file); if (config_data.contains("platform")) { - config_user_and_system.platform = config_data["platform"].get(); + cfg.platform = config_data["platform"].get(); } if (config_data.contains("device")) { - config_user_and_system.device = config_data["device"].get(); + cfg.device = config_data["device"].get(); } if (config_data.contains("queues")) { - config_user_and_system.queues = config_data["queues"].get(); - } - if (config_data.contains("verbosity")) { - config_user_and_system.verbosity = config_data["verbosity"].get(); + cfg.queues = config_data["queues"].get(); } if (config_data.contains("profiling")) { - config_user_and_system.profiling = config_data["profiling"].get(); + cfg.profiling = config_data["profiling"].get(); } if (config_data.contains("allocator")) { - config_user_and_system.allocator = config_data["allocator"].get(); + cfg.allocator = config_data["allocator"].get(); } if (config_data.contains("allocator_size")) { - config_user_and_system.allocator_size = config_data["allocator_size"].get(); + cfg.allocator_size = config_data["allocator_size"].get(); + } + if (config_data.contains("default_wgs")) { + cfg.default_wgs = config_data["default_wgs"].get(); + } + if (config_data.contains("wave_size")) { + cfg.wave_size = config_data["wave_size"].get(); + } + if (config_data.contains("verbosity")) { + cfg.verbosity = config_data["verbosity"].get(); } return ConfigStatus::Ok; } catch (const nlohmann::json::exception& e) { + std::cerr << "Failed to parse config files" << std::endl; std::cerr << "Error parsing JSON file '" << path << "': " << e.what() << std::endl; return ConfigStatus::UserOrSystemConfParseError; } } - ConfigStatus parse_system_and_user_conf() { - std::string sys_dir = config_cli_and_env.system_config_path.value_or(get_default_system_config_path()); - std::string user_dir = config_cli_and_env.user_config_path.value_or(get_default_user_config_path()); + ConfigStatus parse_system_and_user_conf(const Config& cli_env_config, Config& file_config) { + std::string sys_dir = cli_env_config.system_config_path.value_or(get_default_system_config_path()); + std::string user_dir = cli_env_config.user_config_path.value_or(get_default_user_config_path()); - bool file_loaded = false; + ConfigStatus status = ConfigStatus::Ok; if (sys_dir != "") { std::string sys_file = find_first_json_file(sys_dir); if (sys_file != "") { std::cout << "Loading system config: " << sys_file << std::endl; - load_from_file(sys_file); - file_loaded = true; - } - } + status = load_from_file(sys_file, file_config); + if (status == ConfigStatus::UserOrSystemConfParseError) return status; + } else + std::cout << "No system config found in: " << sys_dir << std::endl; + } else + std::cout << "System config directory is not set. Skipping." << std::endl; if (user_dir != "") { std::string user_file = find_first_json_file(user_dir); if (user_file != "") { std::cout << "Loading user config: " << user_file << std::endl; - load_from_file(user_file); - file_loaded = true; - } - } + status = load_from_file(user_file, file_config); + if (status == ConfigStatus::UserOrSystemConfParseError) return status; + } else + std::cout << "No user config found in: " << user_dir << std::endl; + } else + std::cout << "User config directory is not set. Skipping." << std::endl; - if (!file_loaded) { - std::cerr << "Warning: No JSON configuration files found." << std::endl; - } + if (status == ConfigStatus::OpenFileError) return status; return ConfigStatus::Ok; } - ConfigStatus parse_cli_and_env(int argc, char** argv) { + std::string get_spla_version() { + return "SPLA version: 0.0.0"; + } + + ConfigStatus parse_cli_and_env(int argc, char** argv, Config& cfg) { CLI::App app{"SPLA configuration"}; - app.add_flag("-sh,--spla-help", config_cli_and_env.help, "Show help and exit"); - app.add_flag("-sv,--spla-version", config_cli_and_env.version, "Show version and exit"); + app.add_flag("-sh,--spla-help", cfg.help, "Show help and exit"); + app.add_flag("-sv,--spla-version", cfg.version, "Show version and exit"); - app.add_option("-ss,--spla-sconf", config_cli_and_env.system_config_path, "Path to system configuration file") + app.add_option("-ss,--spla-sconf", cfg.system_config_path, + "Path to system configuration file\n" + "Config key: (not used in config file)") ->envname("SPLA_SYSTEM_CONFIG_PATH"); - app.add_option("-su,--spla-uconf", config_cli_and_env.user_config_path, "Path to user configuration file") + app.add_option("-su,--spla-uconf", cfg.user_config_path, + "Path to user configuration file\n" + "Config key: (not used in config file)") ->envname("SPLA_USER_CONFIG_PATH"); - app.add_option("-sp,--spla-platform", config_cli_and_env.platform, "OpenCL platform index") - ->envname("SPLA_OPENCL_PLATFORM") - ->check(CLI::PositiveNumber); + app.add_option("-sp,--spla-platform", cfg.platform, + "OpenCL platform index\n" + "Config key: platform") + ->envname("SPLA_OPENCL_PLATFORM"); - app.add_option("-sd,--spla-device", config_cli_and_env.device, "OpenCL device index") - ->envname("SPLA_OPENCL_DEVICE") - ->check(CLI::PositiveNumber); + app.add_option("-sd,--spla-device", cfg.device, + "OpenCL device index\n" + "Config key: device") + ->envname("SPLA_OPENCL_DEVICE"); - app.add_option("-sq,--spla-queues", config_cli_and_env.queues, "Number of command queues") - ->envname("SPLA_QUEUES") - ->check(CLI::PositiveNumber); + app.add_option("-sq,--spla-queues", cfg.queues, + "Number of command queues\n" + "Config key: queues") + ->envname("SPLA_QUEUES"); - app.add_flag("-pr,--spla-profiling", config_cli_and_env.profiling, "Enable profiling of command queues") + app.add_flag("-pr,--spla-profiling", cfg.profiling, + "Enable profiling of command queues\n" + "Config key: profiling\n") ->envname("SPLA_PROFILING"); - app.add_option("-sa,--spla-allocator", config_cli_and_env.allocator, "Allocator type: linear or general") - ->envname("SPLA_ALLOCATOR") - ->check(CLI::IsMember({"linear", "general"})); - - app.add_option("-sS,--spla-allocator-size", config_cli_and_env.allocator_size, "Linear allocator size in bytes") - ->envname("SPLA_ALLOCATOR_SIZE") - ->check(CLI::PositiveNumber); - - app.add_option("-sV,--spla-verbosity", config_cli_and_env.verbosity, "Verbosity level (0-3)") - ->envname("SPLA_VERBOSITY") - ->check(CLI::Range(0, 3)); + app.add_option("-sa,--spla-allocator", cfg.allocator, + "Allocator type: linear or general\n" + "Config key: allocator") + ->envname("SPLA_ALLOCATOR"); + + app.add_option("-as,--spla-allocator-size", cfg.allocator_size, + "Linear allocator size in bytes\n" + "Required for 'linear' allocator. Ignored for 'general'.\n" + "Config key: allocator_size") + ->envname("SPLA_ALLOCATOR_SIZE"); + + app.add_option("-dw,--spla-default-wgs", cfg.default_wgs, + "Default work group size\n" + "Config key: default_wgs") + ->envname("SPLA_DEFAULT_WGS"); + + app.add_option("ws,--spla-wave-size", cfg.wave_size, + "Wave size for device\n" + "Config key: wave_size") + ->envname("SPLA_WAVE_SIZE"); + + app.add_option("-sV,--spla-verbosity", cfg.verbosity, + "Verbosity level:\n" + " 0: No output\n" + " 1: Errors only\n" + " 2: Errors + warnings\n" + " 3: All messages (info, warnings, errors)") + ->envname("SPLA_VERBOSITY"); try { app.parse(argc, argv); } catch (const CLI::ParseError& e) { + std::cerr << "Failed to parse CLI/ENV" << std::endl; app.exit(e); return ConfigStatus::CliOrEnvParseError; } - if (config_cli_and_env.help) { + if (cfg.help) { std::cout << app.help() << std::endl; return ConfigStatus::HelpRequested; } - if (config_cli_and_env.version) { + if (cfg.version) { std::cout << get_spla_version() << std::endl; return ConfigStatus::VersionRequested; } @@ -249,17 +276,126 @@ namespace spla { return ConfigStatus::Ok; } - ConfigStatus validate() { - if (!config_final.has_all_required()) { - std::cerr << "Error: Missing required configuration parameters" << std::endl; - std::exit(1); + ConfigStatus check_platform_and_device(int platform_index, int device_index) { + if (platform_index < 0) { + std::cerr << "Error: platform must be >= 0 (got " << platform_index << ")" << std::endl; + return ConfigStatus::InvalidConfigParams; + } + + std::vector platforms; + cl::Platform::get(&platforms); + + if (static_cast(platform_index) >= platforms.size()) { + std::cerr << "Error: Platform " << platform_index << " not found" << std::endl; + return ConfigStatus::PlatformNotFound; + } + + if (device_index < 0) { + std::cerr << "Error: device must be >= 0 (got " << device_index << ")" << std::endl; + return ConfigStatus::InvalidConfigParams; + } + + std::vector devices; + platforms[platform_index].getDevices(CL_DEVICE_TYPE_ALL, &devices); + + if (static_cast(device_index) >= devices.size()) { + std::cerr << "Error: Device " << device_index << " not found on platform " << platform_index; + std::cerr << ". Available devices: " << devices.size() << std::endl; + return ConfigStatus::DeviceNotFound; + } + + return ConfigStatus::Ok; + } + + + ConfigStatus validate(const Config& cfg) { + + if (!cfg.platform.has_value()) { + std::cerr << "Error: platform is required" << std::endl; + return ConfigStatus::MissedParametrs; + } + if (!cfg.device.has_value()) { + std::cerr << "Error: device is required" << std::endl; + return ConfigStatus::MissedParametrs; + } + if (!cfg.queues.has_value()) { + std::cerr << "Error: queues is required" << std::endl; + return ConfigStatus::MissedParametrs; + } + if (!cfg.profiling.has_value()) { + std::cerr << "Error: profiling is required" << std::endl; + return ConfigStatus::MissedParametrs; + } + if (!cfg.allocator.has_value()) { + std::cerr << "Error: allocator is required" << std::endl; + return ConfigStatus::MissedParametrs; + } + if (cfg.allocator.value() == "linear" && !cfg.allocator_size.has_value()) { + std::cerr << "Error: allocator_size is required for linear allocator" << std::endl; + return ConfigStatus::MissedParametrs; + } + if (!cfg.default_wgs.has_value()) { + std::cerr << "Error: default wgs is required" << std::endl; + return ConfigStatus::MissedParametrs; + } + if (!cfg.wave_size.has_value()) { + std::cerr << "Error: wave size is required" << std::endl; + return ConfigStatus::MissedParametrs; + } + if (!cfg.verbosity.has_value()) { + std::cerr << "Error: verbosity is required" << std::endl; + return ConfigStatus::MissedParametrs; + } + + + ConfigStatus status; + + status = check_platform_and_device(*cfg.platform, *cfg.device); + if (status != ConfigStatus::Ok) { + return status; + } + + + if (*cfg.queues <= 0) { + std::cerr << "Error: queues must be > 0 (got " << *cfg.queues << ")" << std::endl; + return ConfigStatus::InvalidConfigParams; + } + + + if (*cfg.allocator != "linear" && *cfg.allocator != "general") { + std::cerr << "Error: allocator must be 'linear' or 'general' (got '" << *cfg.allocator << "')" << std::endl; + return ConfigStatus::InvalidConfigParams; + } + + if (*cfg.allocator == "linear") { + if (*cfg.allocator_size == 0) { + std::cerr << "Error: allocator_size must be > 0 for linear allocator" << std::endl; + return ConfigStatus::InvalidConfigParams; + } + } + + + if (*cfg.default_wgs <= 0) { + std::cerr << "Error: default_wgs must be > 0 (got " << *cfg.default_wgs << ")" << std::endl; + return ConfigStatus::InvalidConfigParams; + } + + if (*cfg.wave_size <= 0) { + std::cerr << "Error: wave_size must be > 0 (got " << *cfg.wave_size << ")" << std::endl; + return ConfigStatus::InvalidConfigParams; + } + + + if (*cfg.verbosity < 0 || *cfg.verbosity > 3) { + std::cerr << "Error: verbosity must be between 0 and 3 (got " << *cfg.verbosity << ")" << std::endl; + return ConfigStatus::InvalidConfigParams; } return ConfigStatus::Ok; } - ConfigStatus apply() { + ConfigStatus apply(const Config& cfg) { return ConfigStatus::Ok; } @@ -268,33 +404,41 @@ namespace spla { config_cli_and_env.reset(); config_final.reset(); - ConfigStatus status = parse_cli_and_env(argc, argv); - - if (status == ConfigStatus::HelpRequested || status == ConfigStatus::VersionRequested) { - return status; - } + ConfigStatus status; - if (status != ConfigStatus::Ok) { - return status; + status = parse_cli_and_env(argc, argv, config_cli_and_env); + if (status != ConfigStatus::CliOrEnvParseError) return status; + else { + std::exit(1); } - status = parse_system_and_user_conf(); - if (status != ConfigStatus::Ok) { - return status; + status = parse_system_and_user_conf(config_cli_and_env, config_user_and_system); + if (status != ConfigStatus::UserOrSystemConfParseError) return status; + else { + std::exit(1); } config_final = config_user_and_system; config_final.merge(config_cli_and_env); - status = validate(); + status = validate(config_final); if (status != ConfigStatus::Ok) { - return status; + std::exit(1); } - status = apply(); - if (status != ConfigStatus::Ok) { - return status; - } + std::cout << "Configuration parametrs:" << std::endl; + std::cout << "OpenCL platform index: " << config_final.platform.value() << std::endl; + std::cout << "OpenCL device index: " << config_final.device.value() << std::endl; + std::cout << "Queues number: " << config_final.queues.value() << std::endl; + std::cout << "Profiling: " << config_final.profiling.value() << std::endl; + std::cout << "Allocator: " << config_final.allocator.value() << std::endl; + if (config_final.allocator == "linear") std::cout << "Linear allocator size: " << config_final.allocator_size.value() << std::endl; + std::cout << "Wave size: " << config_final.wave_size.value() << std::endl; + std::cout << "Default wgs: " << config_final.default_wgs.value() << std::endl; + std::cout << "Verbosity: " << config_final.verbosity.value() << std::endl; + + status = apply(config_final); + if (status != ConfigStatus::Ok) std::exit(1); return ConfigStatus::Ok; } diff --git a/src/opencl/cl_configure.hpp b/src/opencl/cl_configure.hpp index 921821f2f..625037c23 100644 --- a/src/opencl/cl_configure.hpp +++ b/src/opencl/cl_configure.hpp @@ -25,11 +25,12 @@ namespace spla { std::optional profiling; std::optional allocator; std::optional allocator_size; + std::optional default_wgs; + std::optional wave_size; std::optional verbosity; void merge(const Config& source); void reset(); - bool has_all_required() const; }; enum ConfigStatus { @@ -39,26 +40,33 @@ namespace spla { CliOrEnvParseError, UserOrSystemConfParseError, - FileError + OpenFileError, + + MissedParametrs, + PlatformNotFound, + DeviceNotFound, + InvalidConfigParams }; - std::string get_spla_version(); + extern Config config_user_and_system; + extern Config config_cli_and_env; + extern Config config_final; std::string get_home_directory(); std::string get_default_system_config_path(); std::string get_default_user_config_path(); std::string find_first_json_file(const std::string& directory); - ConfigStatus load_from_file(const std::string& path); - ConfigStatus parse_cli_and_env(int argc, char** argv); - ConfigStatus parse_system_and_user_conf(); + ConfigStatus load_from_file(const std::string& path, Config& cfg); - ConfigStatus validate(); - ConfigStatus apply(); + ConfigStatus parse_system_and_user_conf(const Config& cli_env_config, Config& file_config); - ConfigStatus configure(int argc, char** argv); + std::string get_spla_version(); + ConfigStatus parse_cli_and_env(int argc, char** argv, Config& cfg); - extern Config config_user_and_system; - extern Config config_cli_and_env; - extern Config config_final; + ConfigStatus check_platform_and_device(int platform_index, int device_index); + ConfigStatus validate(const Config& cfg); + ConfigStatus apply(const Config& cfg); + + ConfigStatus configure(int argc, char** argv); }// namespace spla \ No newline at end of file From f8cea2911a44ccff6db52ef912d018f12a48ff7d Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Tue, 28 Jul 2026 20:37:47 +0500 Subject: [PATCH 22/25] changed init --- src/opencl/cl_accelerator.cpp | 154 ++++++++-------------------------- 1 file changed, 34 insertions(+), 120 deletions(-) diff --git a/src/opencl/cl_accelerator.cpp b/src/opencl/cl_accelerator.cpp index 6a7a0517a..1f53fbac6 100644 --- a/src/opencl/cl_accelerator.cpp +++ b/src/opencl/cl_accelerator.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -40,168 +41,81 @@ namespace spla { CLAccelerator::~CLAccelerator() = default; Status CLAccelerator::init() { - m_description = "no platform or device"; - const char* spla_opencl_platform = std::getenv(SPLA_OPENCL_PLATFORM); - const char* spla_opencl_device = std::getenv(SPLA_OPENCL_DEVICE); - int platform_index = (spla_opencl_platform ? std::atoi(spla_opencl_platform) : 0); - int device_index = (spla_opencl_device ? std::atoi(spla_opencl_device) : 0); + int index_platform = config_final.platform.value(); + int index_device = config_final.device.value(); + int queues_count = config_final.queues.value(); + bool profiling = config_final.profiling.value_or(false); + std::string allocator_type = config_final.allocator.value(); + size_t lin_alloc_size = config_final.allocator_size.value_or(CLAllocLinear::DEFAULT_SIZE); + int default_wgs = config_final.default_wgs.value_or(64); + int wave_size = config_final.wave_size.value_or(32); + int verbosity = config_final.verbosity.value(); - if (set_platform(platform_index) != Status::Ok) - return Status::PlatformNotFound; - - if (set_device(device_index) != Status::Ok) - return Status::DeviceNotFound; - - if (set_queues_count(1) != Status::Ok) - return Status::Error; + //set_verbosity(verbosity); m_cache = std::make_unique(); - // Output handy info - LOG_MSG(Status::Ok, "Initialize accelerator: " << get_description()); - - return Status::Ok; - } - Status CLAccelerator::set_platform(int index) { std::vector available_platforms; cl::Platform::get(&available_platforms); - if (available_platforms.empty()) { - LOG_MSG(Status::PlatformNotFound, "no platform to select for OpenCL acceleration, check your system runtime"); - return Status::PlatformNotFound; - } - if (available_platforms.size() <= index) { - LOG_MSG(Status::InvalidArgument, "index out of list of available platforms"); - return Status::InvalidArgument; - } - m_counter_pool.reset(); m_alloc_general.reset(); m_alloc_linear.reset(); m_alloc_tmp = nullptr; - m_device = cl::Device(); - m_platform = available_platforms[index]; + m_device = cl::Device(); + m_platform = available_platforms[index_platform]; LOG_MSG(Status::Ok, "select OpenCL platform " << m_platform.getInfo()); - return Status::Ok; - } - Status CLAccelerator::set_device(int index) { std::vector available_devices; m_platform.getDevices(CL_DEVICE_TYPE_GPU, &available_devices); - if (available_devices.empty()) { - LOG_MSG(Status::DeviceNotFound, "no device in selected platform, check your OpenCL runtime"); - return Status::DeviceNotFound; - } - if (available_devices.size() <= index) { - LOG_MSG(Status::DeviceNotFound, "index out of list of available devices"); - return Status::DeviceNotFound; - } - - m_device = available_devices[index]; + m_device = available_devices[index_device]; LOG_MSG(Status::Ok, "select OpenCL device " << m_device.getInfo()); - m_vendor_code.clear(); - m_vendor_name = m_device.getInfo(); - m_vendor_id = m_device.getInfo(); - m_max_cu = m_device.getInfo(); - m_max_wgs = m_device.getInfo(); + m_vendor_name = m_device.getInfo(); + m_vendor_id = m_device.getInfo(); + m_max_cu = m_device.getInfo(); + m_max_wgs = m_device.getInfo(); m_max_local_mem = m_device.getInfo(); - m_addr_align = m_device.getInfo() / 8;// from bits to bytes - - m_is_nvidia = false; - m_is_amd = false; - m_is_intel = false; - m_is_img = false; - - if (m_vendor_name.find("Intel") != std::string::npos || - m_vendor_name.find("intel") != std::string::npos || - m_vendor_name.find("INTEL") != std::string::npos || - m_vendor_id == 32902) { - m_vendor_code = VENDOR_CODE_INTEL; - m_default_wgs = 64; - m_wave_size = 8; - m_is_intel = true; - } - if (m_vendor_name.find("Nvidia") != std::string::npos || - m_vendor_name.find("nvidia") != std::string::npos || - m_vendor_name.find("NVIDIA") != std::string::npos || - m_vendor_id == 4318) { - m_vendor_code = VENDOR_CODE_NVIDIA; - m_default_wgs = 64; - m_wave_size = 32; - m_is_nvidia = true; - } - if (m_vendor_name.find("Amd") != std::string::npos || - m_vendor_name.find("amd") != std::string::npos || - m_vendor_name.find("AMD") != std::string::npos || - m_vendor_name.find("Advanced Micro Devices") != std::string::npos || - m_vendor_name.find("advanced micro devices") != std::string::npos || - m_vendor_name.find("ADVANCED MICRO DEVICES") != std::string::npos) { - m_vendor_code = VENDOR_CODE_AMD; - m_default_wgs = 64; - m_wave_size = 64; - m_is_amd = true; - - // Likely, it is an integrated amd device - if (m_max_wgs <= 256 || m_max_cu == 1) m_wave_size = 16; - } - if (m_vendor_name.find("Imagination Technologies") != std::string::npos || - m_vendor_name.find("IMG") != std::string::npos || - m_vendor_name.find("img") != std::string::npos || - m_vendor_id == 0x1010) { - m_vendor_code = VENDOR_CODE_IMG; - m_default_wgs = 32; - m_wave_size = 32; - m_is_img = true; - } - - if (m_vendor_code.empty()) { - LOG_MSG(Status::Error, "failed to match one of the pre-defined vendors"); - m_default_wgs = 64; - m_wave_size = 8; - } + m_addr_align = m_device.getInfo() / 8; + m_default_wgs = default_wgs; + m_wave_size = wave_size; std::stringstream desc; desc << "OpenCL Acc " << m_platform.getInfo() << " device: " << m_device.getInfo() - << " vendor:" << m_vendor_code << " mcu:" << m_max_cu << " wave:" << m_wave_size << " mwgs:" << m_max_wgs; - m_description = desc.str(); - LOG_MSG(Status::Ok, m_description); - return Status::Ok; - } - Status CLAccelerator::set_queues_count(int count) { m_context = cl::Context(m_device); m_queues.clear(); - m_queues.reserve(count); + m_queues.reserve(queues_count); - for (int i = 0; i < count; i++) { + for (int i = 0; i < queues_count; i++) { cl_command_queue_properties properties = 0; -#ifndef SPLA_RELEASE - properties = CL_QUEUE_PROFILING_ENABLE; -#endif + if (profiling) { + properties |= CL_QUEUE_PROFILING_ENABLE; + } cl::CommandQueue queue(m_context, properties); m_queues.emplace_back(std::move(queue)); } - m_counter_pool = std::make_unique(); + m_counter_pool = std::make_unique(); m_alloc_general = std::make_unique(); - m_alloc_tmp = m_alloc_general.get(); - if (!is_nvidia()) { - m_alloc_linear = std::make_unique(CLAllocLinear::DEFAULT_SIZE, m_addr_align); - m_alloc_tmp = m_alloc_linear.get(); + if (allocator_type == "linear") { + m_alloc_linear = std::make_unique(lin_alloc_size, m_addr_align); + m_alloc_tmp = m_alloc_linear.get(); + } else { + m_alloc_tmp = m_alloc_general.get(); } - LOG_MSG(Status::Ok, "configure " << count << " queues for computations"); + LOG_MSG(Status::Ok, "configure " << queues_count << " queues for computations"); return Status::Ok; } const std::string& CLAccelerator::get_name() { @@ -214,4 +128,4 @@ namespace spla { return m_suffix; } -}// namespace spla +}// namespace spla \ No newline at end of file From 0af14328fd66a4796b603474382875eabd07ef9e Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Wed, 29 Jul 2026 22:32:38 +0500 Subject: [PATCH 23/25] made apply() and started changing cl_accelerator.cpp,.hpp + added num_of_mem_banks param --- src/opencl/cl_accelerator.cpp | 203 ++++++++++++++++++++++++++++------ src/opencl/cl_accelerator.hpp | 31 ++++-- src/opencl/cl_configure.cpp | 82 ++++++++++++-- src/opencl/cl_configure.hpp | 5 +- 4 files changed, 272 insertions(+), 49 deletions(-) diff --git a/src/opencl/cl_accelerator.cpp b/src/opencl/cl_accelerator.cpp index 1f53fbac6..8a986e1bd 100644 --- a/src/opencl/cl_accelerator.cpp +++ b/src/opencl/cl_accelerator.cpp @@ -31,7 +31,6 @@ #include #include #include -#include #include @@ -41,83 +40,225 @@ namespace spla { CLAccelerator::~CLAccelerator() = default; Status CLAccelerator::init() { + m_description = "no platform or device"; + + - int index_platform = config_final.platform.value(); - int index_device = config_final.device.value(); - int queues_count = config_final.queues.value(); - bool profiling = config_final.profiling.value_or(false); - std::string allocator_type = config_final.allocator.value(); - size_t lin_alloc_size = config_final.allocator_size.value_or(CLAllocLinear::DEFAULT_SIZE); - int default_wgs = config_final.default_wgs.value_or(64); - int wave_size = config_final.wave_size.value_or(32); - int verbosity = config_final.verbosity.value(); - //set_verbosity(verbosity); m_cache = std::make_unique(); + LOG_MSG(Status::Ok, "Initialize accelerator: " << get_description()); + + return Status::Ok; + } + + + Status CLAccelerator::set_platform(int index) { std::vector available_platforms; cl::Platform::get(&available_platforms); + if (available_platforms.empty()) { + LOG_MSG(Status::PlatformNotFound, "no platform to select for OpenCL acceleration"); + return Status::PlatformNotFound; + } + + if (index < 0) { + LOG_MSG(Status::InvalidArgument, "platform index must be >= 0 (got " << index << ")"); + return Status::InvalidArgument; + } + + if (available_platforms.size() <= static_cast(index)) { + LOG_MSG(Status::InvalidArgument, "platform index out of range (got " << index << ", max " << available_platforms.size() - 1 << ")"); + return Status::InvalidArgument; + } + m_counter_pool.reset(); m_alloc_general.reset(); m_alloc_linear.reset(); m_alloc_tmp = nullptr; - m_device = cl::Device(); - m_platform = available_platforms[index_platform]; + m_device = cl::Device(); + + m_platform = available_platforms[index]; LOG_MSG(Status::Ok, "select OpenCL platform " << m_platform.getInfo()); + return Status::Ok; + } + + + Status CLAccelerator::set_device(int index) { + m_vendor_code.clear(); + std::vector available_devices; m_platform.getDevices(CL_DEVICE_TYPE_GPU, &available_devices); - m_device = available_devices[index_device]; + if (available_devices.empty()) { + LOG_MSG(Status::DeviceNotFound, "no device to select for OpenCL acceleration"); + return Status::DeviceNotFound; + } + + if (index < 0) { + LOG_MSG(Status::InvalidArgument, "device index must be >= 0 (got " << index << ")"); + return Status::InvalidArgument; + } + + if (available_devices.size() <= static_cast(index)) { + LOG_MSG(Status::InvalidArgument, "platform index out of range (got " << index << ", max " << available_devices.size() - 1 << ")"); + return Status::InvalidArgument; + } + + m_device = available_devices[index]; LOG_MSG(Status::Ok, "select OpenCL device " << m_device.getInfo()); - m_vendor_name = m_device.getInfo(); - m_vendor_id = m_device.getInfo(); - m_max_cu = m_device.getInfo(); - m_max_wgs = m_device.getInfo(); + m_vendor_code.clear(); + m_vendor_name = m_device.getInfo(); + m_vendor_id = m_device.getInfo(); + m_max_cu = m_device.getInfo(); + m_max_wgs = m_device.getInfo(); m_max_local_mem = m_device.getInfo(); - m_addr_align = m_device.getInfo() / 8; + m_addr_align = m_device.getInfo() / 8;// from bits to bytes - m_default_wgs = default_wgs; - m_wave_size = wave_size; + m_is_nvidia = false; + m_is_amd = false; + m_is_intel = false; + m_is_img = false; + + if (m_vendor_name.find("Intel") != std::string::npos || + m_vendor_name.find("intel") != std::string::npos || + m_vendor_name.find("INTEL") != std::string::npos || + m_vendor_id == 32902) { + m_vendor_code = VENDOR_CODE_INTEL; + m_is_intel = true; + } + if (m_vendor_name.find("Nvidia") != std::string::npos || + m_vendor_name.find("nvidia") != std::string::npos || + m_vendor_name.find("NVIDIA") != std::string::npos || + m_vendor_id == 4318) { + m_vendor_code = VENDOR_CODE_NVIDIA; + m_is_nvidia = true; + } + if (m_vendor_name.find("Amd") != std::string::npos || + m_vendor_name.find("amd") != std::string::npos || + m_vendor_name.find("AMD") != std::string::npos || + m_vendor_name.find("Advanced Micro Devices") != std::string::npos || + m_vendor_name.find("advanced micro devices") != std::string::npos || + m_vendor_name.find("ADVANCED MICRO DEVICES") != std::string::npos) { + m_vendor_code = VENDOR_CODE_AMD; + m_is_amd = true; + } + if (m_vendor_name.find("Imagination Technologies") != std::string::npos || + m_vendor_name.find("IMG") != std::string::npos || + m_vendor_name.find("img") != std::string::npos || + m_vendor_id == 0x1010) { + m_vendor_code = VENDOR_CODE_IMG; + m_is_img = true; + } + if (m_vendor_code.empty()) { + LOG_MSG(Status::Error, "failed to match one of the pre-defined vendors"); + } std::stringstream desc; desc << "OpenCL Acc " << m_platform.getInfo() << " device: " << m_device.getInfo() + << " vendor:" << m_vendor_code << " mcu:" << m_max_cu << " wave:" << m_wave_size << " mwgs:" << m_max_wgs; + m_description = desc.str(); + LOG_MSG(Status::Ok, m_description); + return Status::Ok; + } + + Status CLAccelerator::set_profiling(bool enabled) { + m_profiling_enabled = enabled; + LOG_MSG(Status::Ok, "set profiling " << (enabled ? "enabled" : "disabled")); + return Status::Ok; + } + + + Status CLAccelerator::set_queues_count(int count) { + if (count <= 0) { + LOG_MSG(Status::InvalidArgument, "queues count must be > 0 (got " << count << ")"); + return Status::InvalidArgument; + } m_context = cl::Context(m_device); m_queues.clear(); - m_queues.reserve(queues_count); + m_queues.reserve(count); - for (int i = 0; i < queues_count; i++) { + for (int i = 0; i < count; i++) { cl_command_queue_properties properties = 0; - if (profiling) { + if (m_profiling_enabled) { properties |= CL_QUEUE_PROFILING_ENABLE; } cl::CommandQueue queue(m_context, properties); m_queues.emplace_back(std::move(queue)); } - m_counter_pool = std::make_unique(); + m_counter_pool = std::make_unique(); m_alloc_general = std::make_unique(); + m_alloc_tmp = m_alloc_general.get(); + + LOG_MSG(Status::Ok, "configure " << count << " queues for computations" + << " (profiling: " << (m_profiling_enabled ? "ON" : "OFF") << ")"); + return Status::Ok; + } + + + Status CLAccelerator::set_linear_allocator(size_t size) { + if (size == 0) { + LOG_MSG(Status::InvalidArgument, "allocator_size must be > 0 for linear allocator (got " << size << ")"); + return Status::InvalidArgument; + } + m_alloc_linear = std::make_unique(size, m_addr_align); + m_alloc_tmp = m_alloc_linear.get(); + LOG_MSG(Status::Ok, "set linear allocator (size: " << size << " bytes)"); + return Status::Ok; + } - if (allocator_type == "linear") { - m_alloc_linear = std::make_unique(lin_alloc_size, m_addr_align); - m_alloc_tmp = m_alloc_linear.get(); - } else { - m_alloc_tmp = m_alloc_general.get(); + + Status CLAccelerator::set_general_allocator() { + m_alloc_tmp = m_alloc_general.get(); + LOG_MSG(Status::Ok, "set general allocator"); + return Status::Ok; + } + + + Status CLAccelerator::set_default_wgs(int wgs) { + if (wgs <= 0) { + LOG_MSG(Status::InvalidArgument, "default_wgs must be > 0 (got " << wgs << ")"); + return Status::InvalidArgument; + } + m_default_wgs = wgs; + LOG_MSG(Status::Ok, "set default work group size: " << wgs); + return Status::Ok; + } + + + Status CLAccelerator::set_wave_size(int size) { + if (size <= 0) { + LOG_MSG(Status::InvalidArgument, "wave_size must be > 0 (got " << size << ")"); + return Status::InvalidArgument; } + m_wave_size = size; + LOG_MSG(Status::Ok, "set wave size: " << size); + return Status::Ok; + } - LOG_MSG(Status::Ok, "configure " << queues_count << " queues for computations"); + + Status CLAccelerator::set_num_of_mem_banks(int banks) { + if (banks <= 0) { + LOG_MSG(Status::InvalidArgument, "num_of_mem_banks must be > 0 (got " << banks << ")"); + return Status::InvalidArgument; + } + m_num_of_mem_banks = banks; + LOG_MSG(Status::Ok, "set num of mem banks: " << banks); return Status::Ok; } + + const std::string& CLAccelerator::get_name() { return m_name; } diff --git a/src/opencl/cl_accelerator.hpp b/src/opencl/cl_accelerator.hpp index 52a0497e1..94b2eadba 100644 --- a/src/opencl/cl_accelerator.hpp +++ b/src/opencl/cl_accelerator.hpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -73,10 +74,13 @@ namespace spla { Status init() override; Status set_platform(int index) override; Status set_device(int index) override; + Status set_profiling(bool enabled); Status set_queues_count(int count) override; - const std::string& get_name() override; - const std::string& get_description() override; - const std::string& get_suffix() override; + Status set_linear_allocator(size_t size); + Status set_general_allocator(); + Status set_default_wgs(int wgs); + Status set_wave_size(int size); + Status set_num_of_mem_banks(int banks); cl::Platform& get_platform() { return m_platform; } cl::Device& get_device() { return m_device; } @@ -87,13 +91,18 @@ namespace spla { class CLAllocGeneral* get_alloc_general() { return m_alloc_general.get(); } class CLAlloc* get_alloc_tmp() { return m_alloc_tmp; } - [[nodiscard]] const std::string& get_vendor_name() const { return m_vendor_name; } + const std::string& get_name() override; + const std::string& get_description() override; + const std::string& get_suffix() override; + [[nodiscard]] const std::string& get_vendor_code() const { return m_vendor_code; } + [[nodiscard]] const std::string& get_vendor_name() const { return m_vendor_name; } [[nodiscard]] uint get_vendor_id() const { return m_vendor_id; } [[nodiscard]] uint get_max_cu() const { return m_max_cu; } [[nodiscard]] uint get_max_wgs() const { return m_max_wgs; } [[nodiscard]] uint get_max_local_mem() const { return m_max_local_mem; } [[nodiscard]] uint get_addr_align() const { return m_addr_align; } + [[nodiscard]] bool get_profiling_enabled() const { return m_profiling_enabled; } [[nodiscard]] uint get_default_wgs() const { return m_default_wgs; } [[nodiscard]] uint get_wave_size() const { return m_wave_size; } [[nodiscard]] uint get_num_of_mem_banks() const { return m_num_of_mem_banks; } @@ -106,6 +115,7 @@ namespace spla { cl::Platform m_platform; cl::Device m_device; cl::Context m_context; + ankerl::svector m_queues; std::unique_ptr m_cache; std::unique_ptr m_counter_pool; std::unique_ptr m_alloc_linear; @@ -115,22 +125,23 @@ namespace spla { std::string m_name = "OpenCL"; std::string m_description; std::string m_suffix = "__cl"; - std::string m_vendor_name; + std::string m_vendor_code; + std::string m_vendor_name; uint m_vendor_id = 0; uint m_max_cu = 0; uint m_max_wgs = 0; uint m_max_local_mem = 0; - uint m_addr_align = 128; - uint m_default_wgs = 64; - uint m_wave_size = 32; - uint m_num_of_mem_banks = 32; + uint m_addr_align = 0; + bool m_profiling_enabled = false; // + uint m_default_wgs = 0; // + uint m_wave_size = 0; // + uint m_num_of_mem_banks = 0; // bool m_is_nvidia = false; bool m_is_amd = false; bool m_is_intel = false; bool m_is_img = false; - ankerl::svector m_queues; }; /** diff --git a/src/opencl/cl_configure.cpp b/src/opencl/cl_configure.cpp index a28f1de2c..ad9001d1f 100644 --- a/src/opencl/cl_configure.cpp +++ b/src/opencl/cl_configure.cpp @@ -1,4 +1,5 @@ #include "cl_configure.hpp" +#include "cl_accelerator.hpp" #include "opencl.hpp" namespace spla { @@ -140,6 +141,9 @@ namespace spla { if (config_data.contains("wave_size")) { cfg.wave_size = config_data["wave_size"].get(); } + if (config_data.contains("num_of_mem_banks")) { + cfg.num_of_mem_banks = config_data["num_of_mem_banks"].get(); + } if (config_data.contains("verbosity")) { cfg.verbosity = config_data["verbosity"].get(); } @@ -247,6 +251,11 @@ namespace spla { "Config key: wave_size") ->envname("SPLA_WAVE_SIZE"); + app.add_option("--spla-mem-banks", config_cli_and_env.num_of_mem_banks, + "Number of memory banks (for optimization)\n" + "Config key: num_of_mem_banks") + ->envname("SPLA_MEM_BANKS"); + app.add_option("-sV,--spla-verbosity", cfg.verbosity, "Verbosity level:\n" " 0: No output\n" @@ -278,6 +287,7 @@ namespace spla { ConfigStatus check_platform_and_device(int platform_index, int device_index) { + if (platform_index < 0) { std::cerr << "Error: platform must be >= 0 (got " << platform_index << ")" << std::endl; return ConfigStatus::InvalidConfigParams; @@ -286,11 +296,17 @@ namespace spla { std::vector platforms; cl::Platform::get(&platforms); + if (platforms.empty()) { + std::cerr << "Error: no platform to select for OpenCL acceleration" << std::endl; + return ConfigStatus::PlatformNotFound; + } + if (static_cast(platform_index) >= platforms.size()) { - std::cerr << "Error: Platform " << platform_index << " not found" << std::endl; + std::cerr << "Error: platform index out of range (got " << platform_index << ", max " << platforms.size() - 1 << ")" << std::endl; return ConfigStatus::PlatformNotFound; } + if (device_index < 0) { std::cerr << "Error: device must be >= 0 (got " << device_index << ")" << std::endl; return ConfigStatus::InvalidConfigParams; @@ -299,9 +315,13 @@ namespace spla { std::vector devices; platforms[platform_index].getDevices(CL_DEVICE_TYPE_ALL, &devices); + if (devices.empty()) { + std::cerr << "Error: no device to select for OpenCL acceleration" << std::endl; + return ConfigStatus::DeviceNotFound; + } + if (static_cast(device_index) >= devices.size()) { - std::cerr << "Error: Device " << device_index << " not found on platform " << platform_index; - std::cerr << ". Available devices: " << devices.size() << std::endl; + std::cerr << "Error: device index out of range (got " << device_index << ", max " << devices.size() - 1 << ")" << std::endl; return ConfigStatus::DeviceNotFound; } @@ -336,11 +356,15 @@ namespace spla { return ConfigStatus::MissedParametrs; } if (!cfg.default_wgs.has_value()) { - std::cerr << "Error: default wgs is required" << std::endl; + std::cerr << "Error: default_wgs is required" << std::endl; return ConfigStatus::MissedParametrs; } if (!cfg.wave_size.has_value()) { - std::cerr << "Error: wave size is required" << std::endl; + std::cerr << "Error: wave_size is required" << std::endl; + return ConfigStatus::MissedParametrs; + } + if (!cfg.num_of_mem_banks.has_value()) { + std::cerr << "Error: num_of_mem_banks is required" << std::endl; return ConfigStatus::MissedParametrs; } if (!cfg.verbosity.has_value()) { @@ -369,8 +393,8 @@ namespace spla { } if (*cfg.allocator == "linear") { - if (*cfg.allocator_size == 0) { - std::cerr << "Error: allocator_size must be > 0 for linear allocator" << std::endl; + if (*cfg.allocator_size <= 0) { + std::cerr << "Error: allocator_size must be > 0 for linear allocator (got " << *cfg.allocator_size << ")" << std::endl; return ConfigStatus::InvalidConfigParams; } } @@ -386,6 +410,11 @@ namespace spla { return ConfigStatus::InvalidConfigParams; } + if (*cfg.num_of_mem_banks <= 0) { + std::cerr << "Error: num_of_mem_banks must be > 0 (got " << *cfg.num_of_mem_banks << ")" << std::endl; + return ConfigStatus::InvalidConfigParams; + } + if (*cfg.verbosity < 0 || *cfg.verbosity > 3) { std::cerr << "Error: verbosity must be between 0 and 3 (got " << *cfg.verbosity << ")" << std::endl; @@ -395,10 +424,48 @@ namespace spla { return ConfigStatus::Ok; } + ConfigStatus apply(const Config& cfg) { + auto* acc = get_acc_cl(); + if (!acc) { + return ConfigStatus::AcceleratorError; + } + + Status status = acc->set_platform(cfg.platform.value()); + if (status != Status::Ok) { + return ConfigStatus::PlatformNotFound; + } + + status = acc->set_device(cfg.device.value()); + if (status != Status::Ok) { + return ConfigStatus::DeviceNotFound; + } + + acc->set_profiling(cfg.profiling.value()); + + status = acc->set_queues_count(cfg.queues.value()); + if (status != Status::Ok) { + return ConfigStatus::AcceleratorError; + } + + if (cfg.allocator.value() == "linear") { + acc->set_linear_allocator(cfg.allocator_size.value()); + } else { + acc->set_general_allocator(); + } + + acc->set_default_wgs(cfg.default_wgs.value()); + acc->set_wave_size(cfg.wave_size.value()); + acc->set_num_of_mem_banks(cfg.num_of_mem_banks.value()); + + status = acc->init(); + if (status != Status::Ok) { + return ConfigStatus::AcceleratorError; + } return ConfigStatus::Ok; } + ConfigStatus configure(int argc, char** argv) { config_user_and_system.reset(); config_cli_and_env.reset(); @@ -435,6 +502,7 @@ namespace spla { if (config_final.allocator == "linear") std::cout << "Linear allocator size: " << config_final.allocator_size.value() << std::endl; std::cout << "Wave size: " << config_final.wave_size.value() << std::endl; std::cout << "Default wgs: " << config_final.default_wgs.value() << std::endl; + std::cout << "Num of mem banks: " << config_final.num_of_mem_banks.value() << std::endl; std::cout << "Verbosity: " << config_final.verbosity.value() << std::endl; status = apply(config_final); diff --git a/src/opencl/cl_configure.hpp b/src/opencl/cl_configure.hpp index 625037c23..5f119a7fa 100644 --- a/src/opencl/cl_configure.hpp +++ b/src/opencl/cl_configure.hpp @@ -27,6 +27,7 @@ namespace spla { std::optional allocator_size; std::optional default_wgs; std::optional wave_size; + std::optional num_of_mem_banks; std::optional verbosity; void merge(const Config& source); @@ -45,7 +46,9 @@ namespace spla { MissedParametrs, PlatformNotFound, DeviceNotFound, - InvalidConfigParams + InvalidConfigParams, + + AcceleratorError }; extern Config config_user_and_system; From 73045f1b8fa533492c56a4f43a05682aa316e6b0 Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Wed, 29 Jul 2026 23:28:22 +0500 Subject: [PATCH 24/25] removed apply(), changed init() -> init(conf) --- src/opencl/cl_accelerator.cpp | 48 +++++++++++++++++++++- src/opencl/cl_accelerator.hpp | 2 +- src/opencl/cl_configure.cpp | 76 ++++++----------------------------- src/opencl/cl_configure.hpp | 5 +-- 4 files changed, 61 insertions(+), 70 deletions(-) diff --git a/src/opencl/cl_accelerator.cpp b/src/opencl/cl_accelerator.cpp index 8a986e1bd..727dabb19 100644 --- a/src/opencl/cl_accelerator.cpp +++ b/src/opencl/cl_accelerator.cpp @@ -39,12 +39,56 @@ namespace spla { CLAccelerator::CLAccelerator() = default; CLAccelerator::~CLAccelerator() = default; - Status CLAccelerator::init() { + Status CLAccelerator::init(const Config& cfg) { + + ConfigStatus config_status; + config_status = validate(cfg); + if (config_status != ConfigStatus::Ok) { + std::exit(1); + } + + std::cout << "Configuration parametrs:" << std::endl; + std::cout << "OpenCL platform index: " << cfg.platform.value() << std::endl; + std::cout << "OpenCL device index: " << cfg.device.value() << std::endl; + std::cout << "Queues number: " << cfg.queues.value() << std::endl; + std::cout << "Profiling: " << cfg.profiling.value() << std::endl; + std::cout << "Allocator: " << cfg.allocator.value() << std::endl; + if (cfg.allocator == "linear") std::cout << "Linear allocator size: " << cfg.allocator_size.value() << std::endl; + std::cout << "Wave size: " << cfg.wave_size.value() << std::endl; + std::cout << "Default wgs: " << cfg.default_wgs.value() << std::endl; + std::cout << "Num of mem banks: " << cfg.num_of_mem_banks.value() << std::endl; + std::cout << "Verbosity: " << cfg.verbosity.value() << std::endl; + m_description = "no platform or device"; - + if (set_platform(cfg.platform.value()) != Status::Ok) + return Status::PlatformNotFound; + + if (set_device(cfg.device.value()) != Status::Ok) + return Status::DeviceNotFound; + + if (set_profiling(cfg.profiling.value()) != Status::Ok) + return Status::Error; + + if (set_queues_count(cfg.queues.value()) != Status::Ok) + return Status::Error; + + if (cfg.allocator.value() == "linear") { + if (set_linear_allocator(cfg.allocator_size.value()) != Status::Ok) + return Status::Error; + } else { + if (set_general_allocator() != Status::Ok) + return Status::Error; + } + + if (set_default_wgs(cfg.default_wgs.value()) != Status::Ok) + return Status::Error; + if (set_wave_size(cfg.wave_size.value()) != Status::Ok) + return Status::Error; + if (set_num_of_mem_banks(cfg.num_of_mem_banks.value()) != Status::Ok) + return Status::Error; m_cache = std::make_unique(); diff --git a/src/opencl/cl_accelerator.hpp b/src/opencl/cl_accelerator.hpp index 94b2eadba..dace84957 100644 --- a/src/opencl/cl_accelerator.hpp +++ b/src/opencl/cl_accelerator.hpp @@ -71,7 +71,7 @@ namespace spla { CLAccelerator(); ~CLAccelerator() override; - Status init() override; + Status init(const Config& cfg) override; Status set_platform(int index) override; Status set_device(int index) override; Status set_profiling(bool enabled); diff --git a/src/opencl/cl_configure.cpp b/src/opencl/cl_configure.cpp index ad9001d1f..8ba4d009b 100644 --- a/src/opencl/cl_configure.cpp +++ b/src/opencl/cl_configure.cpp @@ -425,62 +425,21 @@ namespace spla { } - ConfigStatus apply(const Config& cfg) { - auto* acc = get_acc_cl(); - if (!acc) { - return ConfigStatus::AcceleratorError; - } - - Status status = acc->set_platform(cfg.platform.value()); - if (status != Status::Ok) { - return ConfigStatus::PlatformNotFound; - } - - status = acc->set_device(cfg.device.value()); - if (status != Status::Ok) { - return ConfigStatus::DeviceNotFound; - } - - acc->set_profiling(cfg.profiling.value()); - - status = acc->set_queues_count(cfg.queues.value()); - if (status != Status::Ok) { - return ConfigStatus::AcceleratorError; - } - - if (cfg.allocator.value() == "linear") { - acc->set_linear_allocator(cfg.allocator_size.value()); - } else { - acc->set_general_allocator(); - } - - acc->set_default_wgs(cfg.default_wgs.value()); - acc->set_wave_size(cfg.wave_size.value()); - acc->set_num_of_mem_banks(cfg.num_of_mem_banks.value()); - - status = acc->init(); - if (status != Status::Ok) { - return ConfigStatus::AcceleratorError; - } - return ConfigStatus::Ok; - } - - ConfigStatus configure(int argc, char** argv) { config_user_and_system.reset(); config_cli_and_env.reset(); config_final.reset(); - ConfigStatus status; + ConfigStatus config_status; - status = parse_cli_and_env(argc, argv, config_cli_and_env); - if (status != ConfigStatus::CliOrEnvParseError) return status; + config_status = parse_cli_and_env(argc, argv, config_cli_and_env); + if (config_status != ConfigStatus::CliOrEnvParseError) return config_status; else { std::exit(1); } - status = parse_system_and_user_conf(config_cli_and_env, config_user_and_system); - if (status != ConfigStatus::UserOrSystemConfParseError) return status; + config_status = parse_system_and_user_conf(config_cli_and_env, config_user_and_system); + if (config_status != ConfigStatus::UserOrSystemConfParseError) return config_status; else { std::exit(1); } @@ -488,26 +447,17 @@ namespace spla { config_final = config_user_and_system; config_final.merge(config_cli_and_env); - status = validate(config_final); - if (status != ConfigStatus::Ok) { + auto* acc = get_acc_cl(); + if (!acc) { std::exit(1); } - std::cout << "Configuration parametrs:" << std::endl; - std::cout << "OpenCL platform index: " << config_final.platform.value() << std::endl; - std::cout << "OpenCL device index: " << config_final.device.value() << std::endl; - std::cout << "Queues number: " << config_final.queues.value() << std::endl; - std::cout << "Profiling: " << config_final.profiling.value() << std::endl; - std::cout << "Allocator: " << config_final.allocator.value() << std::endl; - if (config_final.allocator == "linear") std::cout << "Linear allocator size: " << config_final.allocator_size.value() << std::endl; - std::cout << "Wave size: " << config_final.wave_size.value() << std::endl; - std::cout << "Default wgs: " << config_final.default_wgs.value() << std::endl; - std::cout << "Num of mem banks: " << config_final.num_of_mem_banks.value() << std::endl; - std::cout << "Verbosity: " << config_final.verbosity.value() << std::endl; - - status = apply(config_final); - if (status != ConfigStatus::Ok) std::exit(1); + Status status = acc->init(config_final); + if (status != Status::Ok) { + std::exit(1); + } return ConfigStatus::Ok; } -}// namespace spla \ No newline at end of file +}// namespace spla + diff --git a/src/opencl/cl_configure.hpp b/src/opencl/cl_configure.hpp index 5f119a7fa..8364a3a34 100644 --- a/src/opencl/cl_configure.hpp +++ b/src/opencl/cl_configure.hpp @@ -46,9 +46,7 @@ namespace spla { MissedParametrs, PlatformNotFound, DeviceNotFound, - InvalidConfigParams, - - AcceleratorError + InvalidConfigParams }; extern Config config_user_and_system; @@ -68,7 +66,6 @@ namespace spla { ConfigStatus check_platform_and_device(int platform_index, int device_index); ConfigStatus validate(const Config& cfg); - ConfigStatus apply(const Config& cfg); ConfigStatus configure(int argc, char** argv); From a28e55e416441cf38bb7b02836c6605df6ac738f Mon Sep 17 00:00:00 2001 From: Gitubrr Date: Wed, 29 Jul 2026 23:31:40 +0500 Subject: [PATCH 25/25] for formatter only --- src/opencl/cl_accelerator.cpp | 2 +- src/opencl/cl_accelerator.hpp | 39 +++++++++++++++++------------------ src/opencl/cl_configure.cpp | 5 ++--- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/opencl/cl_accelerator.cpp b/src/opencl/cl_accelerator.cpp index 727dabb19..0060d1d3e 100644 --- a/src/opencl/cl_accelerator.cpp +++ b/src/opencl/cl_accelerator.cpp @@ -246,7 +246,7 @@ namespace spla { m_alloc_tmp = m_alloc_general.get(); LOG_MSG(Status::Ok, "configure " << count << " queues for computations" - << " (profiling: " << (m_profiling_enabled ? "ON" : "OFF") << ")"); + << " (profiling: " << (m_profiling_enabled ? "ON" : "OFF") << ")"); return Status::Ok; } diff --git a/src/opencl/cl_accelerator.hpp b/src/opencl/cl_accelerator.hpp index dace84957..00aed7200 100644 --- a/src/opencl/cl_accelerator.hpp +++ b/src/opencl/cl_accelerator.hpp @@ -31,8 +31,8 @@ #include #include #include -#include #include +#include #include #include @@ -71,11 +71,11 @@ namespace spla { CLAccelerator(); ~CLAccelerator() override; - Status init(const Config& cfg) override; - Status set_platform(int index) override; - Status set_device(int index) override; - Status set_profiling(bool enabled); - Status set_queues_count(int count) override; + Status init(const Config& cfg) override; + Status set_platform(int index) override; + Status set_device(int index) override; + Status set_profiling(bool enabled); + Status set_queues_count(int count) override; Status set_linear_allocator(size_t size); Status set_general_allocator(); Status set_default_wgs(int wgs); @@ -128,20 +128,19 @@ namespace spla { std::string m_vendor_code; std::string m_vendor_name; - uint m_vendor_id = 0; - uint m_max_cu = 0; - uint m_max_wgs = 0; - uint m_max_local_mem = 0; - uint m_addr_align = 0; - bool m_profiling_enabled = false; // - uint m_default_wgs = 0; // - uint m_wave_size = 0; // - uint m_num_of_mem_banks = 0; // - bool m_is_nvidia = false; - bool m_is_amd = false; - bool m_is_intel = false; - bool m_is_img = false; - + uint m_vendor_id = 0; + uint m_max_cu = 0; + uint m_max_wgs = 0; + uint m_max_local_mem = 0; + uint m_addr_align = 0; + bool m_profiling_enabled = false;// + uint m_default_wgs = 0; // + uint m_wave_size = 0; // + uint m_num_of_mem_banks = 0; // + bool m_is_nvidia = false; + bool m_is_amd = false; + bool m_is_intel = false; + bool m_is_img = false; }; /** diff --git a/src/opencl/cl_configure.cpp b/src/opencl/cl_configure.cpp index 8ba4d009b..1e3591bef 100644 --- a/src/opencl/cl_configure.cpp +++ b/src/opencl/cl_configure.cpp @@ -252,8 +252,8 @@ namespace spla { ->envname("SPLA_WAVE_SIZE"); app.add_option("--spla-mem-banks", config_cli_and_env.num_of_mem_banks, - "Number of memory banks (for optimization)\n" - "Config key: num_of_mem_banks") + "Number of memory banks (for optimization)\n" + "Config key: num_of_mem_banks") ->envname("SPLA_MEM_BANKS"); app.add_option("-sV,--spla-verbosity", cfg.verbosity, @@ -460,4 +460,3 @@ namespace spla { return ConfigStatus::Ok; } }// namespace spla -