1. Обзор
Эта DLL обеспечивает связь с SSPU и операции Sloppy. Каждая операция передает входные данные устройству SSPU, выполняет вычисление с указанными параметрами и получает выходные данные.
Приближенные функции активации
SloppySigmoid, SloppyTanh, SloppySiLU, SloppyGeLU, SloppySoftmax
Целочисленные операции с насыщением
IntAddSat, IntSubSat, IntMulSat
Подключение устройства
Connect
2. Рабочая среда
| Параметр | Значение |
|---|---|
| Поддерживаемая ОС | Windows 64-bit |
| Поддерживаемая архитектура | x64 |
| Целевая платформа | .NET 8.0 |
| Требуемые права | Права администратора |
| Библиотека-зависимость | System.Management.dll |
| Файлы среды выполнения | Нет |
| Состав | SSPU.dll (один файл) |
3. Подключение
3.1 Предварительные условия
- Установите .NET 8.0 SDK или более позднюю версию.
- Запускайте приложение с правами администратора.
- Разместите SSPU.dll в доступном пути.
3.2 Добавление ссылки
// Add a reference to SSPU.dll
// Option A: Visual Studio: right-click project -> Add Reference -> Browse
// Option B: add this to .csproj:
<Reference Include="SSPU">
<HintPath>path\to\SSPU.dll</HintPath>
</Reference>3.3 Шаги интеграции
using SSPU;
// 1. Create an instance
var sspu = new SSPUDevice();
// 2. Connect the device
int result = sspu.Connect();
if (result != 0) {
Console.WriteLine($"Connection failed: {result}");
return;
}
// 3. Run an operation (SloppySigmoid example)
byte[] inBuffer = PrepareInputData(...);
byte[] outBuffer = new byte[expectedOutputSize];
result = sspu.SloppySigmoid(inBuffer, outBuffer, param_n, param_b);
// 4. Prefer asynchronous execution
await Task.Run(() => sspu.SloppySigmoid(inBuffer, outBuffer, param_n, param_b));4. Спецификация API
4.1 Список методов
| Метод | Функция |
|---|---|
| Connect | Установление соединения с устройством SSPU |
| SloppySigmoid | Приближенная функция активации Sigmoid |
| SloppyTanh | Приближенная функция активации Tanh |
| SloppySiLU | Приближенная функция активации SiLU |
| SloppyGeLU | Приближенная функция активации GeLU |
| SloppySoftmax | Приближенная функция активации Softmax |
| IntAddSat | Знаковое сложение с насыщением |
| IntSubSat | Знаковое вычитание с насыщением |
| IntMulSat | Знаковое умножение с насыщением |
4.1.1 Connect
Устанавливает соединение с устройством SSPU. Этот метод необходимо вызвать до любого другого вычислительного метода.
int Connect()Возвращаемое значение
0 = нормальное завершение (подключение успешно); отрицательное значение = ошибка
- Вызовите перед использованием любого вычислительного метода.
- При неудачном подключении последующие вычислительные вызовы возвращают -1.
4.1.2 SloppySigmoid
Выполняет приближенную функцию активации Sigmoid. Входные данные передаются устройству SSPU, затем возвращается результат вычисления.
int SloppySigmoid(byte[] inBuffer, byte[] outBuffer, byte param_n, byte param_b)| Параметр | Тип | Описание |
|---|---|---|
| inBuffer | byte[] | Массив входных данных (см. 5.3) |
| outBuffer | byte[] | Массив выходных данных (см. 5.4) |
| param_n | byte | Параметр N - общая разрядность (3-32) |
| param_b | byte | Параметр B - разрядность дробной части |
Возвращаемое значение
0 = нормальное завершение; отрицательное значение = ошибка (см. 4.2)
- Требования к входным и выходным данным приведены в главе 5.
- Используйте асинхронный вызов: await Task.Run(() => sspu.SloppySigmoid(...)).
4.1.3 SloppyTanh
Выполняет приближенную функцию активации Tanh. Входные данные передаются устройству SSPU, затем возвращается результат вычисления.
int SloppyTanh(byte[] inBuffer, byte[] outBuffer, byte param_n, byte param_b)| Параметр | Тип | Описание |
|---|---|---|
| inBuffer | byte[] | Массив входных данных |
| outBuffer | byte[] | Массив выходных данных |
| param_n | byte | Параметр N - общая разрядность (3-32) |
| param_b | byte | Параметр B - разрядность дробной части |
Возвращаемое значение
0 = нормальное завершение; отрицательное значение = ошибка (см. 4.2)
- Используйте асинхронный вызов: await Task.Run(...).
4.1.4 SloppySiLU
Выполняет приближенную функцию активации SiLU. Входные данные передаются устройству SSPU, затем возвращается результат вычисления.
int SloppySiLU(byte[] inBuffer, byte[] outBuffer, byte param_n, byte param_b)| Параметр | Тип | Описание |
|---|---|---|
| inBuffer | byte[] | Массив входных данных |
| outBuffer | byte[] | Массив выходных данных |
| param_n | byte | Параметр N - общая разрядность (3-32) |
| param_b | byte | Параметр B - разрядность дробной части |
Возвращаемое значение
0 = нормальное завершение; отрицательное значение = ошибка (см. 4.2)
- Используйте асинхронный вызов: await Task.Run(...).
4.1.5 SloppyGeLU
Выполняет приближенную функцию активации GeLU. Входные данные передаются устройству SSPU, затем возвращается результат вычисления.
int SloppyGeLU(byte[] inBuffer, byte[] outBuffer, byte param_n, byte param_b)| Параметр | Тип | Описание |
|---|---|---|
| inBuffer | byte[] | Массив входных данных |
| outBuffer | byte[] | Массив выходных данных |
| param_n | byte | Параметр N - общая разрядность (3-32) |
| param_b | byte | Параметр B - разрядность дробной части |
Возвращаемое значение
0 = нормальное завершение; отрицательное значение = ошибка (см. 4.2)
- Используйте асинхронный вызов: await Task.Run(...).
4.1.6 SloppySoftmax
Выполняет приближенную функцию активации Softmax. Одна группа содержит 2^d элементов.
int SloppySoftmax(byte[] inBuffer, byte[] outBuffer, byte param_n, byte param_b, byte param_d, byte param_mode = 0)| Параметр | Тип | Описание |
|---|---|---|
| inBuffer | byte[] | Массив входных данных |
| outBuffer | byte[] | Массив выходных данных |
| param_n | byte | Параметр N - общая разрядность |
| param_b | byte | Параметр B - разрядность дробной части |
| param_d | byte | Параметр D - показатель числа элементов в группе (одна группа = 2^d элементов) |
| param_mode | byte | Выбор режима (по умолчанию 0; см. таблицу ниже) |
Возвращаемое значение
0 = нормальное завершение; отрицательное значение = ошибка (см. 4.2)
- Одна операция обрабатывает 2^d элементов как одну группу.
- Ограничение одного вызова: число групп <= 15872 / 2^d.
- Число входных элементов должно быть кратно 2^d (полные группы).
- Это приближенная операция; результат может отклоняться примерно на +/-1 младший разряд.
- Используйте асинхронный вызов: await Task.Run(...).
| Режим | Тип | Допустимый диапазон параметров |
|---|---|---|
| 0 (по умолчанию) | Упрощенный | 3 <= n <= 32, b >= 0, 2 <= d <= 13, 2 <= n-b <= d+1 |
| 1 | Стандартный | 7 <= n <= 32, b >= 4, d >= 1, 3 <= n-b <= d+2 |
| 2+ | Зарезервировано | Зарезервировано; не используется |
4.1.7 IntAddSat
Выполняет знаковое сложение с насыщением. При выходе результата за диапазон типа возвращается максимальное или минимальное значение этого типа.
int IntAddSat(byte[] aBuffer, byte[] bBuffer, byte[] outBuffer, byte param_n)| Параметр | Тип | Описание |
|---|---|---|
| aBuffer | byte[] | Входной массив A (операнд A) |
| bBuffer | byte[] | Входной массив B (операнд B) |
| outBuffer | byte[] | Выходной массив (A + B) |
| param_n | byte | Параметр N - общая разрядность (2-32) |
Возвращаемое значение
0 = нормальное завершение; отрицательное значение = ошибка (см. 4.2)
- Вход и выход являются знаковыми целыми; разрядность задает param_n.
- Используйте асинхронный вызов: await Task.Run(...).
4.1.8 IntSubSat
Выполняет знаковое вычитание с насыщением. При выходе результата за диапазон типа возвращается максимальное или минимальное значение этого типа.
int IntSubSat(byte[] aBuffer, byte[] bBuffer, byte[] outBuffer, byte param_n)| Параметр | Тип | Описание |
|---|---|---|
| aBuffer | byte[] | Входной массив A (уменьшаемое) |
| bBuffer | byte[] | Входной массив B (вычитаемое) |
| outBuffer | byte[] | Выходной массив (A - B) |
| param_n | byte | Параметр N - общая разрядность (2-32) |
Возвращаемое значение
0 = нормальное завершение; отрицательное значение = ошибка (см. 4.2)
- Используйте асинхронный вызов: await Task.Run(...).
4.1.9 IntMulSat
Выполняет знаковое умножение с насыщением. Поддерживается выходная разрядность k; при k = 2n полный продукт сохраняется без насыщения.
int IntMulSat(byte[] aBuffer, byte[] bBuffer, byte[] outBuffer, byte param_n, byte param_k)| Параметр | Тип | Описание |
|---|---|---|
| aBuffer | byte[] | Входной массив A (операнд A) |
| bBuffer | byte[] | Входной массив B (операнд B) |
| outBuffer | byte[] | Выходной массив (A x B) |
| param_n | byte | Параметр N - разрядность каждого операнда (2-16) |
| param_k | byte | Параметр K - выходная разрядность (n-2n; без насыщения при k = 2n) |
Возвращаемое значение
0 = нормальное завершение; отрицательное значение = ошибка (см. 4.2)
- A и B - знаковые n-битные целые.
- При k = 2n полный продукт сохраняется без отсечения насыщением.
- Используйте асинхронный вызов: await Task.Run(...).
4.2 Ошибки
| Код ошибки | Описание |
|---|---|
| 0 | Нормальное завершение |
| -1 | Нет подключения (дескриптор устройства не получен; Connect не вызывался или завершился ошибкой) |
| -2 | Не удалось получить свободный BankID (ошибка обработки или свободный Bank не найден) |
| -3 | Не удалось отправить команду SetDataDMA |
| -4 | Не удалось отправить команду StartCalculation |
| -5 | Не удалось отправить GetBankStatus (ошибка отправки или истекло время опроса статуса) |
| -6 | Не удалось отправить команду GetDataDMA |
| -10 | Ошибка передачи списка команд |
| -11 | Ошибка создания списка команд |
| -12 | Входные данные превышают лимит одного вызова или число элементов SloppySoftmax не кратно 2^d |
5. Спецификация входных и выходных данных
5.1 Термины
| Термин | Описание |
|---|---|
| n | Разрядность одного входного значения (например, 22 бита) |
| b | Разрядность дробной части |
| d | Только для SloppySoftmax: показатель числа элементов в группе (одна группа = 2^d элементов) |
| k | Только для IntMulSat: выходная разрядность (n-2n) |
| I(s, m, b) | Формат с фиксированной точкой: s = число знаковых битов, m = целая часть, b = дробная часть, общая ширина = s + m + b |
| bytesPerData | Байт на элемент: вход = (n+7)/8; выход вычисляется по выходной разрядности |
| elementCount | Число элементов = inBuffer.length / ((n+7)/8) |
| LSB first | Храните биты последовательно, начиная с bit0 (младший бит) |
5.2 Типы входа и выхода
| Метод | Тип входа | Тип выхода | Выходная разрядность | Тип результата |
|---|---|---|---|---|
| SloppySigmoid | I(1, n-1-b, b) | I(0, 0, b+2) | b + 2 | Беззнаковый (0-1) |
| SloppyTanh | I(1, n-1-b, b) | I(1, 0, b) | b + 1 | Знаковый (-1 до +1) |
| SloppySiLU | I(1, n-1-b, b) | I(1, n-1-b, b) | n | Знаковый |
| SloppyGeLU | I(1, n-1-b, b) | I(1, n-1-b, b) | n | Знаковый |
| SloppySoftmax | I(1, n-1-b, b) | I(0, 0, n) | n | Беззнаковый (0-1) |
| IntAddSat | I(1, n-1, 0) | I(1, n-1, 0) | n | Знаковый |
| IntSubSat | I(1, n-1, 0) | I(1, n-1, 0) | n | Знаковый |
| IntMulSat | I(1, n-1, 0) | I(1, k-1, 0) | k | Знаковый |
5.3 Входные данные
Процесс подготовки входных данных
- Маскируйте значение до n бит (например, используйте только младшие 22 бита).
- Выполните знаковое расширение: если старший бит равен 1, считайте значение отрицательным и заполните старшие биты единицами.
- Упакуйте биты, начиная с младшего (LSB first).
- Храните каждый элемент в (n + 7) / 8 байтах; неиспользуемые биты последнего байта не применяются.
Пример расположения битов (n = 22 -> 3 байта/элемент)
| Байт | Содержимое битов |
|---|---|
| Byte0 | bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 |
| Byte1 | bit15 bit14 bit13 bit12 bit11 bit10 bit9 bit8 |
| Byte2 | [unused] [unused] bit21 bit20 bit19 bit18 bit17 bit16 |
Пример входа: {45, -73} (n = 22)
// Byte sequence for {45, -73} (n = 22, 3 bytes/data):
// 45 -> 0x00002D -> Byte0: 0x2D, Byte1: 0x00, Byte2: 0x00
// -73 -> 0x3FFFB7 -> Byte0: 0xB7, Byte1: 0xFF, Byte2: 0x3F
//
// Final inBuffer: 2D 00 00 B7 FF 3FПримечания по входу/выходу SloppySoftmax
- Вход состоит из последовательных групп Softmax; каждая группа содержит 2^d последовательных элементов.
- Выход возвращается в том же порядке групп.
- Число входных элементов должно быть кратно 2^d (полные группы).
- Это приближенная операция; результат может отклоняться примерно на +/-1 младший разряд.
5.4 Выходные данные
Процесс восстановления выходных данных
- Восстановите биты выходной разрядности в порядке LSB first.
- Интерпретируйте знак в соответствии с выходным типом.
- Знаковые (Tanh / SiLU / GeLU): используйте старший бит как знаковый и выполните знаковое расширение.
- Беззнаковые (Sigmoid / Softmax): не выполняйте знаковое расширение (дробь с фиксированной точкой не меньше 0).
Выделение буфера
| Метод | Выходная разрядность | Байт на элемент |
|---|---|---|
| SloppySigmoid | b + 2 | (b + 2 + 7) / 8 |
| SloppyTanh | b + 1 | (b + 1 + 7) / 8 |
| SloppySiLU / GeLU / Softmax | n | (n + 7) / 8 |
| IntAddSat / IntSubSat | n | (n + 7) / 8 |
| IntMulSat | k | (k + 7) / 8 |
5.5 Ограничение емкости
Один вычислительный вызов обрабатывает не более одной страницы устройства: эффективная область содержит 15872 элемента. Вызовы сверх лимита должен разбивать вызывающий код.
| Категория функций | Лимит одного вызова | Примечание |
|---|---|---|
| Sigmoid / Tanh / SiLU / GeLU / IntAddSat / IntSubSat / IntMulSat | elementCount <= 15872 | В единицах элементов |
| SloppySoftmax | Число групп <= 15872 / 2^d | Число входных элементов должно быть кратно 2^d |
Примеры максимального числа групп SloppySoftmax
| d | Лимит одного вызова |
|---|---|
| 2 | 3968 групп |
| 9 | 31 группа |
| 13 | 1 группа |
| 14+ | Не поддерживается |
Важно: При превышении лимита возвращается код ошибки -12. SloppySoftmax также возвращает -12, если число входных элементов не кратно 2^d.