HLSF use long as aloloc size
This commit is contained in:
+747
-747
File diff suppressed because it is too large
Load Diff
@@ -1,36 +1,36 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(StgSharp.Native C)
|
||||
|
||||
# Include helper for external libraries if present
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/ExternalLibs.cmake OPTIONAL)
|
||||
|
||||
# Add main source directory
|
||||
# Follow naming convention: prefer sn-src/sn-head (StgSharp native naming).
|
||||
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/sn-src)
|
||||
add_subdirectory(sn-src)
|
||||
elseif(EXISTS ${CMAKE_CURRENT_LIST_DIR}/src)
|
||||
add_subdirectory(src)
|
||||
else()
|
||||
message(STATUS "No sn-src/ or src/ directory in StgSharp.Native; create one to add sources.")
|
||||
endif()
|
||||
|
||||
# Register include directories according to naming convention: sn-head preferred
|
||||
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/sn-head)
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/sn-head)
|
||||
elseif(EXISTS ${CMAKE_CURRENT_LIST_DIR}/include)
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
|
||||
endif()
|
||||
|
||||
# Discover external libraries laid out under external/<libname> (each with head/ and lib/)
|
||||
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/external)
|
||||
file(GLOB EXTERNAL_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/external/*)
|
||||
foreach(_d ${EXTERNAL_DIRS})
|
||||
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/external/${_d}")
|
||||
if(COMMAND use_external_lib)
|
||||
use_external_lib(${_d} "${CMAKE_CURRENT_SOURCE_DIR}/external/${_d}")
|
||||
else()
|
||||
message(STATUS "External lib '${_d}' found at external/${_d} (no use_external_lib defined).")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(StgSharp.Native C)
|
||||
|
||||
# Include helper for external libraries if present
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/ExternalLibs.cmake OPTIONAL)
|
||||
|
||||
# Add main source directory
|
||||
# Follow naming convention: prefer sn-src/sn-head (StgSharp native naming).
|
||||
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/sn-src)
|
||||
add_subdirectory(sn-src)
|
||||
elseif(EXISTS ${CMAKE_CURRENT_LIST_DIR}/src)
|
||||
add_subdirectory(src)
|
||||
else()
|
||||
message(STATUS "No sn-src/ or src/ directory in StgSharp.Native; create one to add sources.")
|
||||
endif()
|
||||
|
||||
# Register include directories according to naming convention: sn-head preferred
|
||||
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/sn-head)
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/sn-head)
|
||||
elseif(EXISTS ${CMAKE_CURRENT_LIST_DIR}/include)
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
|
||||
endif()
|
||||
|
||||
# Discover external libraries laid out under external/<libname> (each with head/ and lib/)
|
||||
if(EXISTS ${CMAKE_CURRENT_LIST_DIR}/external)
|
||||
file(GLOB EXTERNAL_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/external/*)
|
||||
foreach(_d ${EXTERNAL_DIRS})
|
||||
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/external/${_d}")
|
||||
if(COMMAND use_external_lib)
|
||||
use_external_lib(${_d} "${CMAKE_CURRENT_SOURCE_DIR}/external/${_d}")
|
||||
else()
|
||||
message(STATUS "External lib '${_d}' found at external/${_d} (no use_external_lib defined).")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
# Helper for external libs layout: external/<libname>/{head,lib}
|
||||
# Provides function `use_external_lib(<name> <path>)` that sets include directories
|
||||
# and attempts to link static/shared libs found under lib/.
|
||||
|
||||
function(use_external_lib NAME PATH)
|
||||
# Expect headers in ${PATH}/head and libs in ${PATH}/lib
|
||||
set(HEAD_DIR "${PATH}/head")
|
||||
set(LIB_DIR "${PATH}/lib")
|
||||
|
||||
if(EXISTS "${HEAD_DIR}")
|
||||
message(STATUS "Registering external include: ${HEAD_DIR}")
|
||||
include_directories(${HEAD_DIR})
|
||||
else()
|
||||
message(WARNING "External lib ${NAME} missing head/ directory at ${HEAD_DIR}")
|
||||
endif()
|
||||
|
||||
if(EXISTS "${LIB_DIR}")
|
||||
# try to find static/shared libs inside LIB_DIR
|
||||
file(GLOB LIB_FILES RELATIVE ${LIB_DIR} ${LIB_DIR}/*)
|
||||
foreach(_lib ${LIB_FILES})
|
||||
if(_lib MATCHES ".*\\.(a|lib|so|dylib)$")
|
||||
message(STATUS "Found library for ${NAME}: ${LIB_DIR}/${_lib}")
|
||||
# Consumer targets should link explicitly; provide variable for convenience
|
||||
set(EXTERNAL_LIB_${NAME} "${LIB_DIR}/${_lib}" PARENT_SCOPE)
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
message(STATUS "No lib/ directory for external lib ${NAME} at ${LIB_DIR}")
|
||||
endif()
|
||||
endfunction()
|
||||
# Helper for external libs layout: external/<libname>/{head,lib}
|
||||
# Provides function `use_external_lib(<name> <path>)` that sets include directories
|
||||
# and attempts to link static/shared libs found under lib/.
|
||||
|
||||
function(use_external_lib NAME PATH)
|
||||
# Expect headers in ${PATH}/head and libs in ${PATH}/lib
|
||||
set(HEAD_DIR "${PATH}/head")
|
||||
set(LIB_DIR "${PATH}/lib")
|
||||
|
||||
if(EXISTS "${HEAD_DIR}")
|
||||
message(STATUS "Registering external include: ${HEAD_DIR}")
|
||||
include_directories(${HEAD_DIR})
|
||||
else()
|
||||
message(WARNING "External lib ${NAME} missing head/ directory at ${HEAD_DIR}")
|
||||
endif()
|
||||
|
||||
if(EXISTS "${LIB_DIR}")
|
||||
# try to find static/shared libs inside LIB_DIR
|
||||
file(GLOB LIB_FILES RELATIVE ${LIB_DIR} ${LIB_DIR}/*)
|
||||
foreach(_lib ${LIB_FILES})
|
||||
if(_lib MATCHES ".*\\.(a|lib|so|dylib)$")
|
||||
message(STATUS "Found library for ${NAME}: ${LIB_DIR}/${_lib}")
|
||||
# Consumer targets should link explicitly; provide variable for convenience
|
||||
set(EXTERNAL_LIB_${NAME} "${LIB_DIR}/${_lib}" PARENT_SCOPE)
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
message(STATUS "No lib/ directory for external lib ${NAME} at ${LIB_DIR}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
+11
-11
@@ -1,11 +1,11 @@
|
||||
StgSharp.Native layout
|
||||
|
||||
Conventions:
|
||||
- src/ : project C sources and CMakeLists.txt calling add_library/add_executable
|
||||
- include/ : public headers (if used)
|
||||
- external/ : third-party libraries, each library lives in its own folder
|
||||
- <libname>/
|
||||
- head/ : header files for the library
|
||||
- lib/ : static or shared lib files (or CMake build for that lib)
|
||||
|
||||
The root `CMakeLists.txt` in this folder includes `ExternalLibs.cmake` if present.
|
||||
StgSharp.Native layout
|
||||
|
||||
Conventions:
|
||||
- src/ : project C sources and CMakeLists.txt calling add_library/add_executable
|
||||
- include/ : public headers (if used)
|
||||
- external/ : third-party libraries, each library lives in its own folder
|
||||
- <libname>/
|
||||
- head/ : header files for the library
|
||||
- lib/ : static or shared lib files (or CMake build for that lib)
|
||||
|
||||
The root `CMakeLists.txt` in this folder includes `ExternalLibs.cmake` if present.
|
||||
|
||||
+197
-197
@@ -1,198 +1,198 @@
|
||||
# SIMDID (x86-64) 64-bit Specification (Completed per fixed layout)
|
||||
|
||||
This document completes the **64-bit SIMDID** bit layout as specified, with emphasis on the design of the **AVX512 Feature section ([31..16])**, so it can cover the messy AVX-512 subsets while keeping branching logic compact. It also allocates an **AVX Feature byte** adjacent to the AVX512/AMX regions for AVX-family capabilities.
|
||||
|
||||
> Convention: bit0 is the least significant bit (LSB). Only x86-64 interpreter semantics are defined here; the header’s Root ISA allows extension to other architectures.
|
||||
|
||||
---
|
||||
|
||||
## 1) ASCII Bit Layout (Final)
|
||||
|
||||
```
|
||||
SIMDID (64 bits) [63 ........................................................ 0]
|
||||
+----------+-----------+----------------+----------------+----------------+----------------+----------------+
|
||||
| [63..56] | [47..40] | [39..32] | [31..16] | [15..8] | [7..4] | [3..0] |
|
||||
| uArchHi | AVX Feat | AMX Future | AVX512 Feature | MainLevel | Manuf | Root |
|
||||
+----------+-----------+----------------+----------------+----------------+----------------+----------------+
|
||||
```
|
||||
|
||||
- **[3..0] Root ISA**: Root ISA type (selects interpreter)
|
||||
- **[7..4] Manufacture**: Vendor info (Intel/AMD for x86)
|
||||
- **[15..8] MainLevel**: Main ISA level (ascending, shared bit semantics)
|
||||
- **[31..16] AVX512 Feature**: AVX-512 features/subsets/implementation form (key part)
|
||||
- **[39..32] AMX Future**: AMX features (few bits for now)
|
||||
- **[47..40] AVX Feature**: AVX-family capabilities (base requires AVX+AVX2; key extensions include FMA/F16C)
|
||||
- **[63..56] uArchHi**: Optional microarchitecture/policy hints (default 0, no functional impact).
|
||||
|
||||
---
|
||||
|
||||
## 2) Root ISA ([3..0])
|
||||
|
||||
Suggested encoding (minimal usable set, expandable if needed):
|
||||
|
||||
| Value | Root ISA |
|
||||
|---:|----------|
|
||||
| 0 | Unknown |
|
||||
| 1 | x86-64 |
|
||||
| 2 | AArch64 |
|
||||
| 3 | PPC64LE |
|
||||
| 4 | Apple Silicon (distinct value as required) |
|
||||
| 5 | RISC-V |
|
||||
| 6 | LoongArch |
|
||||
| 7..15 | Reserved |
|
||||
|
||||
> Note: Architecturally Apple Silicon is AArch64; a distinct value is provided here because the Root ISA layer may distinguish it. Interpreter choice is up to implementation.
|
||||
|
||||
---
|
||||
|
||||
## 3) Manufacture ([7..4])
|
||||
|
||||
For **x86-64**:
|
||||
|
||||
| Value | Manufacture |
|
||||
|---:|-------------|
|
||||
| 0 | Unknown/Other |
|
||||
| 1 | Intel |
|
||||
| 2 | AMD |
|
||||
| 3 | VIA/Zhaoxin |
|
||||
| 4..15 | Reserved |
|
||||
|
||||
For other Root ISAs, this nibble is defined by their interpreters (e.g., Apple/Qualcomm/MediaTek for ARM).
|
||||
|
||||
---
|
||||
|
||||
## 4) MainLevel ([15..8], ascending)
|
||||
|
||||
"Shared bits and ascending" means higher values indicate higher capability (or later scheduling order). Suggested values:
|
||||
|
||||
| Value | MainLevel |
|
||||
|---:|-----------|
|
||||
| 0 | NONE |
|
||||
| 1 | SSE (full SSE family: SSE1..SSE4.2) |
|
||||
| 2 | AVX2 |
|
||||
| 3 | AVX2_FMA |
|
||||
| 4 | AVX2_FMA_F16C (from this level onward, 16-bit types are supported) |
|
||||
| 5 | AVX512 (check [31..16]) |
|
||||
| 6 | AMX |
|
||||
| 7 | AVX10 |
|
||||
| 8..255 | Reserved |
|
||||
|
||||
> Scheduling suggestion: `MainLevel` is the primary switch; only when `MainLevel >= AVX512` should `AVX512 Feature` be parsed; only when `MainLevel >= AMX` should `AMX Future` be parsed. AVX Feature sits beside AMX/AVX512 and is meaningful when AVX or higher is present.
|
||||
|
||||
---
|
||||
|
||||
## 5) AVX512 Feature ([31..16]) Design Goals (Compact)
|
||||
|
||||
1) **Base AVX512 one-shot check**: Use 1 bit for the bundle `F + CD + VL + DQ + BW`, avoiding multiple subset checks.
|
||||
2) **Glue vs native**: Use an implementation field to distinguish `AVX512-DUAL` (glue/downclock risk) from `AVX512-NATIVE` (full 512-bit ALU).
|
||||
3) **Niche/AI extensions separated**: VNNI, BF16/FP16, and similar extensions each get a dedicated bit so the base path stays simple.
|
||||
|
||||
---
|
||||
|
||||
## 6) AVX512 Feature Bit Layout ([31..16] = 16 bits, compact)
|
||||
|
||||
AVX512 Feature (bits 31..16)
|
||||
|
||||
| **bit** | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
|
||||
|-----------|-----|-----|------|------|------|-------|------|------|-------|-------|----|------|----|----|----|----|
|
||||
| **Usage** | R | R | FP16 | BF16 | VNNI | VBMI2 | VBMI | R/AI | Impl1 | Impl0 | R | BASE | R | R | R | R |
|
||||
|
||||
Notes:
|
||||
|
||||
- **BASE (bit 20)**: Base AVX512 bundle, indicating `F + CD + VL + DQ + BW` are all present. If set to 1, the detecting side must guarantee these subsets are all available.
|
||||
- **AVX512_IMPL ([23..22], 2-bit)**: Implementation form (width policy).
|
||||
|
||||
| Value | Meaning |
|
||||
|---:|------|
|
||||
| 0 | Unknown (strategy decided by Manufacture/uArch) |
|
||||
| 1 | AVX512-DUAL (glue/downclock risk; prefer 256-bit path) |
|
||||
| 2 | AVX512-NATIVE (full 512-bit ALU; 512-bit path is usable) |
|
||||
| 3 | Reserved |
|
||||
|
||||
- **VBMI/VBMI2/VNNI/BF16/FP16 ([29..26])**: Commonly needed niche or AI-related small-type extensions; set as needed.
|
||||
- **R/AI (bit 24)**: Reserved for future AI or other non-crypto extensions.
|
||||
- **[31..30], [21], [19..16]**: Reserved for future allocation.
|
||||
|
||||
---
|
||||
|
||||
## 7) AVX Feature Byte ([47..40], 8 bits)
|
||||
|
||||
Purpose: compact AVX-family capability encoding adjacent to AVX512/AMX. Base requirement: AVX **and** AVX2 present. Key extensions: FMA and F16C. Additional bits reserved for other extensions.
|
||||
|
||||
AVX Feature (bits 47..40)
|
||||
|
||||
| bit | 47 | 46 | 45 | 44 | 43 | 42 | 41 | 40 |
|
||||
|-----|----|----|----|----|----|----|----|----|
|
||||
| use | R | R | R | R | F16C | FMA | AVX2 | AVX |
|
||||
|
||||
Rules:
|
||||
- **AVX (bit 40)**: AVX present.
|
||||
- **AVX2 (bit 41)**: AVX2 present. For the AVX feature byte to be considered valid, both AVX and AVX2 must be set.
|
||||
- **FMA (bit 42)**: FMA present.
|
||||
- **F16C (bit 43)**: F16C present.
|
||||
- **[44..47]**: Reserved for other AVX-family extensions (e.g., BMI/BMI2, IFMA, XOP) as needed.
|
||||
|
||||
---
|
||||
|
||||
## 8) "AVX512BASE" Determination (Single Check)
|
||||
|
||||
- **Rule**: `BASE=1` implies `F+CD+VL+DQ+BW` are all present; no need for per-subset checks. Detection must keep this consistent; if not all subsets are present, set to 0.
|
||||
- **Runtime branching**:
|
||||
- If `MainLevel < AVX512`: fall back to AVX2/FMA path.
|
||||
- Otherwise:
|
||||
- Check `BASE`; if 0, fall back to AVX2/FMA (or treat as detection failure).
|
||||
- Check `AVX512_IMPL`: `DUAL` uses 256-bit/downclock-safe path, `NATIVE` uses 512-bit path.
|
||||
- When small-type/AI capabilities are required, consult `VNNI/BF16/FP16/VBMI/VBMI2` bits.
|
||||
|
||||
---
|
||||
|
||||
## 9) AMX Future ([39..32], 8 bits)
|
||||
|
||||
A single byte is reserved; define three common bits for now, leave the rest reserved:
|
||||
|
||||
| bit (relative to [39..32]) | Name | Note |
|
||||
|---:|------|------|
|
||||
| 0 | AMX_TILE | Tile base |
|
||||
| 1 | AMX_INT8 | INT8 tile |
|
||||
| 2 | AMX_BF16 | BF16 tile |
|
||||
| 3..7 | Reserved | |
|
||||
|
||||
When `MainLevel < AMX`, this byte can be all zeros.
|
||||
|
||||
---
|
||||
|
||||
## 10) uArchHi ([63..56], 8 bits)
|
||||
|
||||
Purpose: optional high-byte strategy field to address issues like early Intel/AMD "glue" AVX512 that are not expressible purely via CPUID subsets. Defaults to 0.
|
||||
|
||||
Suggested minimal use:
|
||||
- `0`: unused
|
||||
- `1`: ForceDual (treat as AVX512-DUAL even if impl is unknown)
|
||||
- `2`: ForceNative (treat as AVX512-NATIVE even if impl is unknown)
|
||||
- `3..`: Implementation-maintained uArch enumeration (e.g., SKX/ICL/SPR/ZEN4/ZEN5…)
|
||||
|
||||
Practical strategy for a single maintainer:
|
||||
- AMD: detection side sets `AVX512_IMPL = DUAL` directly (no uArch needed)
|
||||
- Intel: enumerate only selected models of interest; otherwise Unknown follows default policy
|
||||
|
||||
---
|
||||
|
||||
## 11) Minimal Detection-Side Fill Rules (x86-64)
|
||||
|
||||
1) Set `RootISA = x86-64`, `Manufacture = Intel/AMD`.
|
||||
2) Compute `MainLevel` (per ascending rule).
|
||||
3) If `MainLevel >= AVX512`:
|
||||
- If `F+CD+VL+DQ+BW` are all present, set `BASE = 1`; otherwise `BASE = 0`.
|
||||
- Set `AVX512_IMPL`:
|
||||
- AMD: DUAL (per definition)
|
||||
- Intel: Decide DUAL/NATIVE based on family/model or policy table; if uncertain, use Unknown
|
||||
- When VNNI/BF16/FP16/VBMI/VBMI2 are detected, set the corresponding bits.
|
||||
4) If `MainLevel >= AMX`: fill the AMX byte.
|
||||
5) When AVX/AVX2 are present, populate the AVX Feature byte: set AVX and AVX2; set FMA and F16C when detected; leave reserved bits for future extensions.
|
||||
6) Use uArchHi only when additional policy is needed; otherwise leave as 0.
|
||||
|
||||
---
|
||||
|
||||
## 12) Choice for High Bits Reservation
|
||||
|
||||
# SIMDID (x86-64) 64-bit Specification (Completed per fixed layout)
|
||||
|
||||
This document completes the **64-bit SIMDID** bit layout as specified, with emphasis on the design of the **AVX512 Feature section ([31..16])**, so it can cover the messy AVX-512 subsets while keeping branching logic compact. It also allocates an **AVX Feature byte** adjacent to the AVX512/AMX regions for AVX-family capabilities.
|
||||
|
||||
> Convention: bit0 is the least significant bit (LSB). Only x86-64 interpreter semantics are defined here; the header’s Root ISA allows extension to other architectures.
|
||||
|
||||
---
|
||||
|
||||
## 1) ASCII Bit Layout (Final)
|
||||
|
||||
```
|
||||
SIMDID (64 bits) [63 ........................................................ 0]
|
||||
+----------+-----------+----------------+----------------+----------------+----------------+----------------+
|
||||
| [63..56] | [47..40] | [39..32] | [31..16] | [15..8] | [7..4] | [3..0] |
|
||||
| uArchHi | AVX Feat | AMX Future | AVX512 Feature | MainLevel | Manuf | Root |
|
||||
+----------+-----------+----------------+----------------+----------------+----------------+----------------+
|
||||
```
|
||||
|
||||
- **[3..0] Root ISA**: Root ISA type (selects interpreter)
|
||||
- **[7..4] Manufacture**: Vendor info (Intel/AMD for x86)
|
||||
- **[15..8] MainLevel**: Main ISA level (ascending, shared bit semantics)
|
||||
- **[31..16] AVX512 Feature**: AVX-512 features/subsets/implementation form (key part)
|
||||
- **[39..32] AMX Future**: AMX features (few bits for now)
|
||||
- **[47..40] AVX Feature**: AVX-family capabilities (base requires AVX+AVX2; key extensions include FMA/F16C)
|
||||
- **[63..56] uArchHi**: Optional microarchitecture/policy hints (default 0, no functional impact).
|
||||
|
||||
---
|
||||
|
||||
## 2) Root ISA ([3..0])
|
||||
|
||||
Suggested encoding (minimal usable set, expandable if needed):
|
||||
|
||||
| Value | Root ISA |
|
||||
|---:|----------|
|
||||
| 0 | Unknown |
|
||||
| 1 | x86-64 |
|
||||
| 2 | AArch64 |
|
||||
| 3 | PPC64LE |
|
||||
| 4 | Apple Silicon (distinct value as required) |
|
||||
| 5 | RISC-V |
|
||||
| 6 | LoongArch |
|
||||
| 7..15 | Reserved |
|
||||
|
||||
> Note: Architecturally Apple Silicon is AArch64; a distinct value is provided here because the Root ISA layer may distinguish it. Interpreter choice is up to implementation.
|
||||
|
||||
---
|
||||
|
||||
## 3) Manufacture ([7..4])
|
||||
|
||||
For **x86-64**:
|
||||
|
||||
| Value | Manufacture |
|
||||
|---:|-------------|
|
||||
| 0 | Unknown/Other |
|
||||
| 1 | Intel |
|
||||
| 2 | AMD |
|
||||
| 3 | VIA/Zhaoxin |
|
||||
| 4..15 | Reserved |
|
||||
|
||||
For other Root ISAs, this nibble is defined by their interpreters (e.g., Apple/Qualcomm/MediaTek for ARM).
|
||||
|
||||
---
|
||||
|
||||
## 4) MainLevel ([15..8], ascending)
|
||||
|
||||
"Shared bits and ascending" means higher values indicate higher capability (or later scheduling order). Suggested values:
|
||||
|
||||
| Value | MainLevel |
|
||||
|---:|-----------|
|
||||
| 0 | NONE |
|
||||
| 1 | SSE (full SSE family: SSE1..SSE4.2) |
|
||||
| 2 | AVX2 |
|
||||
| 3 | AVX2_FMA |
|
||||
| 4 | AVX2_FMA_F16C (from this level onward, 16-bit types are supported) |
|
||||
| 5 | AVX512 (check [31..16]) |
|
||||
| 6 | AMX |
|
||||
| 7 | AVX10 |
|
||||
| 8..255 | Reserved |
|
||||
|
||||
> Scheduling suggestion: `MainLevel` is the primary switch; only when `MainLevel >= AVX512` should `AVX512 Feature` be parsed; only when `MainLevel >= AMX` should `AMX Future` be parsed. AVX Feature sits beside AMX/AVX512 and is meaningful when AVX or higher is present.
|
||||
|
||||
---
|
||||
|
||||
## 5) AVX512 Feature ([31..16]) Design Goals (Compact)
|
||||
|
||||
1) **Base AVX512 one-shot check**: Use 1 bit for the bundle `F + CD + VL + DQ + BW`, avoiding multiple subset checks.
|
||||
2) **Glue vs native**: Use an implementation field to distinguish `AVX512-DUAL` (glue/downclock risk) from `AVX512-NATIVE` (full 512-bit ALU).
|
||||
3) **Niche/AI extensions separated**: VNNI, BF16/FP16, and similar extensions each get a dedicated bit so the base path stays simple.
|
||||
|
||||
---
|
||||
|
||||
## 6) AVX512 Feature Bit Layout ([31..16] = 16 bits, compact)
|
||||
|
||||
AVX512 Feature (bits 31..16)
|
||||
|
||||
| **bit** | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
|
||||
|-----------|-----|-----|------|------|------|-------|------|------|-------|-------|----|------|----|----|----|----|
|
||||
| **Usage** | R | R | FP16 | BF16 | VNNI | VBMI2 | VBMI | R/AI | Impl1 | Impl0 | R | BASE | R | R | R | R |
|
||||
|
||||
Notes:
|
||||
|
||||
- **BASE (bit 20)**: Base AVX512 bundle, indicating `F + CD + VL + DQ + BW` are all present. If set to 1, the detecting side must guarantee these subsets are all available.
|
||||
- **AVX512_IMPL ([23..22], 2-bit)**: Implementation form (width policy).
|
||||
|
||||
| Value | Meaning |
|
||||
|---:|------|
|
||||
| 0 | Unknown (strategy decided by Manufacture/uArch) |
|
||||
| 1 | AVX512-DUAL (glue/downclock risk; prefer 256-bit path) |
|
||||
| 2 | AVX512-NATIVE (full 512-bit ALU; 512-bit path is usable) |
|
||||
| 3 | Reserved |
|
||||
|
||||
- **VBMI/VBMI2/VNNI/BF16/FP16 ([29..26])**: Commonly needed niche or AI-related small-type extensions; set as needed.
|
||||
- **R/AI (bit 24)**: Reserved for future AI or other non-crypto extensions.
|
||||
- **[31..30], [21], [19..16]**: Reserved for future allocation.
|
||||
|
||||
---
|
||||
|
||||
## 7) AVX Feature Byte ([47..40], 8 bits)
|
||||
|
||||
Purpose: compact AVX-family capability encoding adjacent to AVX512/AMX. Base requirement: AVX **and** AVX2 present. Key extensions: FMA and F16C. Additional bits reserved for other extensions.
|
||||
|
||||
AVX Feature (bits 47..40)
|
||||
|
||||
| bit | 47 | 46 | 45 | 44 | 43 | 42 | 41 | 40 |
|
||||
|-----|----|----|----|----|----|----|----|----|
|
||||
| use | R | R | R | R | F16C | FMA | AVX2 | AVX |
|
||||
|
||||
Rules:
|
||||
- **AVX (bit 40)**: AVX present.
|
||||
- **AVX2 (bit 41)**: AVX2 present. For the AVX feature byte to be considered valid, both AVX and AVX2 must be set.
|
||||
- **FMA (bit 42)**: FMA present.
|
||||
- **F16C (bit 43)**: F16C present.
|
||||
- **[44..47]**: Reserved for other AVX-family extensions (e.g., BMI/BMI2, IFMA, XOP) as needed.
|
||||
|
||||
---
|
||||
|
||||
## 8) "AVX512BASE" Determination (Single Check)
|
||||
|
||||
- **Rule**: `BASE=1` implies `F+CD+VL+DQ+BW` are all present; no need for per-subset checks. Detection must keep this consistent; if not all subsets are present, set to 0.
|
||||
- **Runtime branching**:
|
||||
- If `MainLevel < AVX512`: fall back to AVX2/FMA path.
|
||||
- Otherwise:
|
||||
- Check `BASE`; if 0, fall back to AVX2/FMA (or treat as detection failure).
|
||||
- Check `AVX512_IMPL`: `DUAL` uses 256-bit/downclock-safe path, `NATIVE` uses 512-bit path.
|
||||
- When small-type/AI capabilities are required, consult `VNNI/BF16/FP16/VBMI/VBMI2` bits.
|
||||
|
||||
---
|
||||
|
||||
## 9) AMX Future ([39..32], 8 bits)
|
||||
|
||||
A single byte is reserved; define three common bits for now, leave the rest reserved:
|
||||
|
||||
| bit (relative to [39..32]) | Name | Note |
|
||||
|---:|------|------|
|
||||
| 0 | AMX_TILE | Tile base |
|
||||
| 1 | AMX_INT8 | INT8 tile |
|
||||
| 2 | AMX_BF16 | BF16 tile |
|
||||
| 3..7 | Reserved | |
|
||||
|
||||
When `MainLevel < AMX`, this byte can be all zeros.
|
||||
|
||||
---
|
||||
|
||||
## 10) uArchHi ([63..56], 8 bits)
|
||||
|
||||
Purpose: optional high-byte strategy field to address issues like early Intel/AMD "glue" AVX512 that are not expressible purely via CPUID subsets. Defaults to 0.
|
||||
|
||||
Suggested minimal use:
|
||||
- `0`: unused
|
||||
- `1`: ForceDual (treat as AVX512-DUAL even if impl is unknown)
|
||||
- `2`: ForceNative (treat as AVX512-NATIVE even if impl is unknown)
|
||||
- `3..`: Implementation-maintained uArch enumeration (e.g., SKX/ICL/SPR/ZEN4/ZEN5…)
|
||||
|
||||
Practical strategy for a single maintainer:
|
||||
- AMD: detection side sets `AVX512_IMPL = DUAL` directly (no uArch needed)
|
||||
- Intel: enumerate only selected models of interest; otherwise Unknown follows default policy
|
||||
|
||||
---
|
||||
|
||||
## 11) Minimal Detection-Side Fill Rules (x86-64)
|
||||
|
||||
1) Set `RootISA = x86-64`, `Manufacture = Intel/AMD`.
|
||||
2) Compute `MainLevel` (per ascending rule).
|
||||
3) If `MainLevel >= AVX512`:
|
||||
- If `F+CD+VL+DQ+BW` are all present, set `BASE = 1`; otherwise `BASE = 0`.
|
||||
- Set `AVX512_IMPL`:
|
||||
- AMD: DUAL (per definition)
|
||||
- Intel: Decide DUAL/NATIVE based on family/model or policy table; if uncertain, use Unknown
|
||||
- When VNNI/BF16/FP16/VBMI/VBMI2 are detected, set the corresponding bits.
|
||||
4) If `MainLevel >= AMX`: fill the AMX byte.
|
||||
5) When AVX/AVX2 are present, populate the AVX Feature byte: set AVX and AVX2; set FMA and F16C when detected; leave reserved bits for future extensions.
|
||||
6) Use uArchHi only when additional policy is needed; otherwise leave as 0.
|
||||
|
||||
---
|
||||
|
||||
## 12) Choice for High Bits Reservation
|
||||
|
||||
Currently `[31..24]` is reserved for AVX512 extensions/AI. `[47..44]` is reserved for AVX-family extensions beside the AVX byte. uArchHi `[63..56]` remains available for minimal policy hints. If IFMA or other extensions are more important, repurpose the reserved bits while keeping `BASE` and `Impl` unchanged.
|
||||
@@ -1,202 +1,202 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="PerformanceDebug|x64">
|
||||
<Configuration>PerformanceDebug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{20cbff26-6746-402e-992c-7b643e9423eb}</ProjectGuid>
|
||||
<RootNamespace>StgSharpC</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>StgSharp.Native</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)build</OutDir>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
<EnableClangTidyCodeAnalysis>false</EnableClangTidyCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)build</OutDir>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
<EnableClangTidyCodeAnalysis>false</EnableClangTidyCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|x64'">
|
||||
<OutDir>$(SolutionDir)build</OutDir>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
<EnableClangTidyCodeAnalysis>false</EnableClangTidyCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>Default</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
||||
<ExpandAttributedSource>true</ExpandAttributedSource>
|
||||
<AssemblerOutput>All</AssemblerOutput>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)lib;$(ProjectDir)sn-head;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>opengl32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<Bscmake>
|
||||
<PreserveSbr>true</PreserveSbr>
|
||||
</Bscmake>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<AssemblerOutput>All</AssemblerOutput>
|
||||
<LanguageStandard>Default</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)lib;$(ProjectDir)sn-head;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>opengl32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ShowProgress>LinkVerbose</ShowProgress>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<AssemblerOutput>All</AssemblerOutput>
|
||||
<LanguageStandard>Default</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)lib;$(ProjectDir)sn-head;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>opengl32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ShowProgress>LinkVerbose</ShowProgress>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="sn-src\m.panel.x86.c" />
|
||||
<ClCompile Include="sn-src\m.basic.x86.c" />
|
||||
<ClCompile Include="sn-src\dllmain.c" />
|
||||
<ClCompile Include="sn-src\m.bufop.x86.c" />
|
||||
<ClCompile Include="sn-src\m.solve.x86.c" />
|
||||
<ClCompile Include="sn-src\m.fma_tile.x86.c" />
|
||||
<ClCompile Include="sn-src\s.factorial.x86.c" />
|
||||
<ClCompile Include="sn-src\m.fma.x86.c" />
|
||||
<ClCompile Include="sn-src\s.hash.x86.c" />
|
||||
<ClCompile Include="sn-src\load_intrinsic.x86.c">
|
||||
<FileType>CCode</FileType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\load_glfw.c" />
|
||||
<ClCompile Include="sn-src\cpuid.x86.c" />
|
||||
<ClCompile Include="sn-src\sn_native.c" />
|
||||
<ClCompile Include="sn-src\str_string.c" />
|
||||
<ClCompile Include="sn-src\vector.c" />
|
||||
<ClCompile Include="sn-src\vector_dot.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="lib\glfw\glfw3.h" />
|
||||
<ClInclude Include="lib\glfw\glfw3native.h" />
|
||||
<ClInclude Include="lib\stbi\stb_image.h" />
|
||||
<ClInclude Include="sn-head\gl.h" />
|
||||
<ClInclude Include="sn-head\glfw_function.h" />
|
||||
<ClInclude Include="sn-head\khrplatform.h" />
|
||||
<ClInclude Include="sn-head\sn_internal.h" />
|
||||
<ClInclude Include="sn-head\sn_intrincontext.x86.h" />
|
||||
<ClInclude Include="sn-head\sn_intrinsic.h" />
|
||||
<ClInclude Include="sn-head\sn_matkernel.h" />
|
||||
<ClInclude Include="sn-head\sn_target.h" />
|
||||
<ClInclude Include="sn-head\StgSharpNative.h" />
|
||||
<ClInclude Include="sn-head\wgl.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Library Include="lib\glfw\glfw3.lib" />
|
||||
<Library Include="lib\glfw\glfw3_mt.lib" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="SIMDID.x86.md" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="PerformanceDebug|x64">
|
||||
<Configuration>PerformanceDebug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{20cbff26-6746-402e-992c-7b643e9423eb}</ProjectGuid>
|
||||
<RootNamespace>StgSharpC</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>StgSharp.Native</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)build</OutDir>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
<EnableClangTidyCodeAnalysis>false</EnableClangTidyCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)build</OutDir>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
<EnableClangTidyCodeAnalysis>false</EnableClangTidyCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|x64'">
|
||||
<OutDir>$(SolutionDir)build</OutDir>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
<EnableClangTidyCodeAnalysis>false</EnableClangTidyCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>Default</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
||||
<ExpandAttributedSource>true</ExpandAttributedSource>
|
||||
<AssemblerOutput>All</AssemblerOutput>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)lib;$(ProjectDir)sn-head;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>opengl32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<Bscmake>
|
||||
<PreserveSbr>true</PreserveSbr>
|
||||
</Bscmake>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<AssemblerOutput>All</AssemblerOutput>
|
||||
<LanguageStandard>Default</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)lib;$(ProjectDir)sn-head;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>opengl32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ShowProgress>LinkVerbose</ShowProgress>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='PerformanceDebug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<AssemblerOutput>All</AssemblerOutput>
|
||||
<LanguageStandard>Default</LanguageStandard>
|
||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)lib;$(ProjectDir)sn-head;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<AdditionalDependencies>opengl32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ShowProgress>LinkVerbose</ShowProgress>
|
||||
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="sn-src\m.panel.x86.c" />
|
||||
<ClCompile Include="sn-src\m.basic.x86.c" />
|
||||
<ClCompile Include="sn-src\dllmain.c" />
|
||||
<ClCompile Include="sn-src\m.bufop.x86.c" />
|
||||
<ClCompile Include="sn-src\m.solve.x86.c" />
|
||||
<ClCompile Include="sn-src\m.fma_tile.x86.c" />
|
||||
<ClCompile Include="sn-src\s.factorial.x86.c" />
|
||||
<ClCompile Include="sn-src\m.fma.x86.c" />
|
||||
<ClCompile Include="sn-src\s.hash.x86.c" />
|
||||
<ClCompile Include="sn-src\load_intrinsic.x86.c">
|
||||
<FileType>CCode</FileType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\load_glfw.c" />
|
||||
<ClCompile Include="sn-src\cpuid.x86.c" />
|
||||
<ClCompile Include="sn-src\sn_native.c" />
|
||||
<ClCompile Include="sn-src\str_string.c" />
|
||||
<ClCompile Include="sn-src\vector.c" />
|
||||
<ClCompile Include="sn-src\vector_dot.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="lib\glfw\glfw3.h" />
|
||||
<ClInclude Include="lib\glfw\glfw3native.h" />
|
||||
<ClInclude Include="lib\stbi\stb_image.h" />
|
||||
<ClInclude Include="sn-head\gl.h" />
|
||||
<ClInclude Include="sn-head\glfw_function.h" />
|
||||
<ClInclude Include="sn-head\khrplatform.h" />
|
||||
<ClInclude Include="sn-head\sn_internal.h" />
|
||||
<ClInclude Include="sn-head\sn_intrincontext.x86.h" />
|
||||
<ClInclude Include="sn-head\sn_intrinsic.h" />
|
||||
<ClInclude Include="sn-head\sn_matkernel.h" />
|
||||
<ClInclude Include="sn-head\sn_target.h" />
|
||||
<ClInclude Include="sn-head\StgSharpNative.h" />
|
||||
<ClInclude Include="sn-head\wgl.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Library Include="lib\glfw\glfw3.lib" />
|
||||
<Library Include="lib\glfw\glfw3_mt.lib" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="SIMDID.x86.md" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,124 +1,124 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Document">
|
||||
<UniqueIdentifier>{fbd74b53-5314-4d9d-a788-07bd1b413f74}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="sn-src\dllmain.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\s.factorial.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\s.hash.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\str_string.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\vector.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\vector_dot.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\sn_native.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\load_glfw.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\m.basic.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\m.fma.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\load_intrinsic.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\m.bufop.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\m.panel.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\m.solve.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\cpuid.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\m.fma_tile.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="sn-head\gl.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\khrplatform.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\sn_internal.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\StgSharpNative.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\wgl.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\glfw_function.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\sn_matkernel.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="lib\glfw\glfw3.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="lib\glfw\glfw3native.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="lib\stbi\stb_image.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\sn_target.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\sn_intrincontext.x86.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\sn_intrinsic.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Library Include="lib\glfw\glfw3.lib">
|
||||
<Filter>资源文件</Filter>
|
||||
</Library>
|
||||
<Library Include="lib\glfw\glfw3_mt.lib">
|
||||
<Filter>资源文件</Filter>
|
||||
</Library>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="SIMDID.x86.md">
|
||||
<Filter>Document</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Document">
|
||||
<UniqueIdentifier>{fbd74b53-5314-4d9d-a788-07bd1b413f74}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="sn-src\dllmain.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\s.factorial.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\s.hash.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\str_string.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\vector.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\vector_dot.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\sn_native.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\load_glfw.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\m.basic.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\m.fma.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\load_intrinsic.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\m.bufop.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\m.panel.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\m.solve.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\cpuid.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sn-src\m.fma_tile.x86.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="sn-head\gl.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\khrplatform.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\sn_internal.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\StgSharpNative.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\wgl.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\glfw_function.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\sn_matkernel.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="lib\glfw\glfw3.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="lib\glfw\glfw3native.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="lib\stbi\stb_image.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\sn_target.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\sn_intrincontext.x86.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sn-head\sn_intrinsic.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Library Include="lib\glfw\glfw3.lib">
|
||||
<Filter>资源文件</Filter>
|
||||
</Library>
|
||||
<Library Include="lib\glfw\glfw3_mt.lib">
|
||||
<Filter>资源文件</Filter>
|
||||
</Library>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="SIMDID.x86.md">
|
||||
<Filter>Document</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LocalDebuggerCommand>$(SolutionDir)Output\x64\Debug\net6.0\StgSharpDebug.exe</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LocalDebuggerCommand>$(SolutionDir)Output\x64\Debug\net6.0\StgSharpDebug.exe</LocalDebuggerCommand>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,9 +1,9 @@
|
||||
# StgSharp c file naming regulation
|
||||
|
||||
| Name Header | Description |
|
||||
|:-------:|:--------|
|
||||
|sn-|Stgsharp Native lib self operation|
|
||||
|k-|Matrix kernel operation|
|
||||
|str-|SIMD boosted stream operation|
|
||||
|load-|Context loading operation|
|
||||
# StgSharp c file naming regulation
|
||||
|
||||
| Name Header | Description |
|
||||
|:-------:|:--------|
|
||||
|sn-|Stgsharp Native lib self operation|
|
||||
|k-|Matrix kernel operation|
|
||||
|str-|SIMD boosted stream operation|
|
||||
|load-|Context loading operation|
|
||||
|##OTHER##-|File from another open source lib with name ##OTHER##|
|
||||
@@ -1,73 +1,73 @@
|
||||
#ifdef _MSC_VER
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef SSC
|
||||
#define SSC
|
||||
|
||||
#include "ssc_internal.h"
|
||||
|
||||
#define STBIDEF SSCAPI
|
||||
#include "stb_image.h"
|
||||
|
||||
#include "gl.h"
|
||||
#include "wgl.h"
|
||||
#include "glfw3.h"
|
||||
#include <immintrin.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef SSCAPI_DEFINE
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SSCAPI __declspec(dllexport)
|
||||
#elif defined _LINUX_
|
||||
#define SSCAPI __attribute__((dllexport))
|
||||
#elif defined _APPLE_
|
||||
#define SSCAPI __attribute__((visibility("default")))
|
||||
#else
|
||||
#define SSCAPI
|
||||
#endif
|
||||
|
||||
#endif // ! SSCAPI_DEFINE
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define byte char
|
||||
#define cs_char uint16_t
|
||||
#define ssc_null_assert(ptr) assert(ptr != NULL)
|
||||
|
||||
#define ALIGN(simdVec) _mm_loadu_ps(&simdVec)
|
||||
#define ALIGN256(simdVec) _mm256_loadu_ps(&simdVec)
|
||||
#define ALIGN512(simdVec) _mm512_loadu_ps(&simdVec)
|
||||
|
||||
typedef struct Image {
|
||||
int width;
|
||||
int height;
|
||||
int channel;
|
||||
char *pixelPtr;
|
||||
} Image;
|
||||
|
||||
typedef char *(*imageLoader)(char const *filename, int *x, int *y, int *channels_in_file,
|
||||
int desired_channels);
|
||||
|
||||
SSCAPI char infolog[512];
|
||||
SSCAPI int SSCDECL glCheckShaderStat(GladGLContext *context, uint64_t shaderHandle, int key,
|
||||
char **logRef);
|
||||
SSCAPI void SSCDECL initGL(int majorVersion, int minorVersion);
|
||||
SSCAPI unsigned int SSCDECL linkShaderProgram(GladGLContext *context, GLuint shadertype);
|
||||
SSCAPI void SSCDECL loadImageData(char *location, Image *out, imageLoader loader);
|
||||
SSCAPI GLFWglproc SSCDECL loadGlfuncDefault(char *procName);
|
||||
SSCAPI void SSCDECL unloadImageData(Image *out);
|
||||
SSCAPI char *SSCDECL readLog(void);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
SSCAPI int SSCDECL load_intrinsic_function(void *intrinsic_context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef SSC
|
||||
#define SSC
|
||||
|
||||
#include "ssc_internal.h"
|
||||
|
||||
#define STBIDEF SSCAPI
|
||||
#include "stb_image.h"
|
||||
|
||||
#include "gl.h"
|
||||
#include "wgl.h"
|
||||
#include "glfw3.h"
|
||||
#include <immintrin.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef SSCAPI_DEFINE
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SSCAPI __declspec(dllexport)
|
||||
#elif defined _LINUX_
|
||||
#define SSCAPI __attribute__((dllexport))
|
||||
#elif defined _APPLE_
|
||||
#define SSCAPI __attribute__((visibility("default")))
|
||||
#else
|
||||
#define SSCAPI
|
||||
#endif
|
||||
|
||||
#endif // ! SSCAPI_DEFINE
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define byte char
|
||||
#define cs_char uint16_t
|
||||
#define ssc_null_assert(ptr) assert(ptr != NULL)
|
||||
|
||||
#define ALIGN(simdVec) _mm_loadu_ps(&simdVec)
|
||||
#define ALIGN256(simdVec) _mm256_loadu_ps(&simdVec)
|
||||
#define ALIGN512(simdVec) _mm512_loadu_ps(&simdVec)
|
||||
|
||||
typedef struct Image {
|
||||
int width;
|
||||
int height;
|
||||
int channel;
|
||||
char *pixelPtr;
|
||||
} Image;
|
||||
|
||||
typedef char *(*imageLoader)(char const *filename, int *x, int *y, int *channels_in_file,
|
||||
int desired_channels);
|
||||
|
||||
SSCAPI char infolog[512];
|
||||
SSCAPI int SSCDECL glCheckShaderStat(GladGLContext *context, uint64_t shaderHandle, int key,
|
||||
char **logRef);
|
||||
SSCAPI void SSCDECL initGL(int majorVersion, int minorVersion);
|
||||
SSCAPI unsigned int SSCDECL linkShaderProgram(GladGLContext *context, GLuint shadertype);
|
||||
SSCAPI void SSCDECL loadImageData(char *location, Image *out, imageLoader loader);
|
||||
SSCAPI GLFWglproc SSCDECL loadGlfuncDefault(char *procName);
|
||||
SSCAPI void SSCDECL unloadImageData(Image *out);
|
||||
SSCAPI char *SSCDECL readLog(void);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
SSCAPI int SSCDECL load_intrinsic_function(void *intrinsic_context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,74 +1,74 @@
|
||||
#ifdef _MSC_VER
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef SNative
|
||||
#define SNative
|
||||
|
||||
#include "sn_internal.h"
|
||||
#include "sn_target.h"
|
||||
|
||||
#define STBIDEF SN_API
|
||||
#include "../lib/stbi/stb_image.h"
|
||||
|
||||
#include "gl.h"
|
||||
#include "wgl.h"
|
||||
#define GLFWAPI INTERNAL
|
||||
#include "glfw\glfw3.h"
|
||||
#include <immintrin.h>
|
||||
#include <assert.h>
|
||||
#include <glfw_function.h>
|
||||
|
||||
#ifndef SN_APIDEF
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SN_API __declspec(dllexport)
|
||||
#elif defined _LINUX_
|
||||
#define SN_API __attribute__((dllexport))
|
||||
#elif defined _APPLE_
|
||||
#define SN_API __attribute__((visibility("default")))
|
||||
#else
|
||||
#define SN_API
|
||||
#endif
|
||||
|
||||
#endif // ! SN_APIDEF
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define byte char
|
||||
#define cs_char uint16_t
|
||||
#define sn_null_assert(ptr) assert(ptr != NULL)
|
||||
|
||||
#define ALIGN(simdVec) _mm_loadu_ps(&simdVec)
|
||||
#define ALIGN256(simdVec) _mm256_loadu_ps(&simdVec)
|
||||
#define ALIGN512(simdVec) _mm512_loadu_ps(&simdVec)
|
||||
|
||||
typedef struct Image {
|
||||
int width;
|
||||
int height;
|
||||
int channel;
|
||||
char *pixelPtr;
|
||||
} Image;
|
||||
|
||||
typedef char *(*imageLoader)(char const *filename, int *x, int *y, int *channels_in_file,
|
||||
int desired_channels);
|
||||
|
||||
SN_API char infolog[512];
|
||||
SN_API int SN_DECL glCheckShaderStat(GladGLContext *context, uint64_t shaderHandle, int key,
|
||||
char **logRef);
|
||||
SN_API void SN_DECL initGL(int majorVersion, int minorVersion);
|
||||
SN_API unsigned int SN_DECL linkShaderProgram(GladGLContext *context, GLuint shadertype);
|
||||
SN_API void SN_DECL loadImageData(char *location, Image *out, imageLoader loader);
|
||||
SN_API GLFWglproc SN_DECL loadGlfuncDefault(char *procName);
|
||||
SN_API void SN_DECL unloadImageData(Image *out);
|
||||
SN_API char *SN_DECL readLog(void);
|
||||
SN_API void SN_DECL load_glfw_functions(GLFWFunctionTable *table);
|
||||
SN_API SIMDID SN_DECL load_intrinsic_function(void *intrinsic_context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef SNative
|
||||
#define SNative
|
||||
|
||||
#include "sn_internal.h"
|
||||
#include "sn_target.h"
|
||||
|
||||
#define STBIDEF SN_API
|
||||
#include "../lib/stbi/stb_image.h"
|
||||
|
||||
#include "gl.h"
|
||||
#include "wgl.h"
|
||||
#define GLFWAPI INTERNAL
|
||||
#include "glfw\glfw3.h"
|
||||
#include <immintrin.h>
|
||||
#include <assert.h>
|
||||
#include <glfw_function.h>
|
||||
|
||||
#ifndef SN_APIDEF
|
||||
|
||||
#ifdef _WIN32
|
||||
#define SN_API __declspec(dllexport)
|
||||
#elif defined _LINUX_
|
||||
#define SN_API __attribute__((dllexport))
|
||||
#elif defined _APPLE_
|
||||
#define SN_API __attribute__((visibility("default")))
|
||||
#else
|
||||
#define SN_API
|
||||
#endif
|
||||
|
||||
#endif // ! SN_APIDEF
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define byte char
|
||||
#define cs_char uint16_t
|
||||
#define sn_null_assert(ptr) assert(ptr != NULL)
|
||||
|
||||
#define ALIGN(simdVec) _mm_loadu_ps(&simdVec)
|
||||
#define ALIGN256(simdVec) _mm256_loadu_ps(&simdVec)
|
||||
#define ALIGN512(simdVec) _mm512_loadu_ps(&simdVec)
|
||||
|
||||
typedef struct Image {
|
||||
int width;
|
||||
int height;
|
||||
int channel;
|
||||
char *pixelPtr;
|
||||
} Image;
|
||||
|
||||
typedef char *(*imageLoader)(char const *filename, int *x, int *y, int *channels_in_file,
|
||||
int desired_channels);
|
||||
|
||||
SN_API char infolog[512];
|
||||
SN_API int SN_DECL glCheckShaderStat(GladGLContext *context, uint64_t shaderHandle, int key,
|
||||
char **logRef);
|
||||
SN_API void SN_DECL initGL(int majorVersion, int minorVersion);
|
||||
SN_API unsigned int SN_DECL linkShaderProgram(GladGLContext *context, GLuint shadertype);
|
||||
SN_API void SN_DECL loadImageData(char *location, Image *out, imageLoader loader);
|
||||
SN_API GLFWglproc SN_DECL loadGlfuncDefault(char *procName);
|
||||
SN_API void SN_DECL unloadImageData(Image *out);
|
||||
SN_API char *SN_DECL readLog(void);
|
||||
SN_API void SN_DECL load_glfw_functions(GLFWFunctionTable *table);
|
||||
SN_API SIMDID SN_DECL load_intrinsic_function(void *intrinsic_context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+10775
-10775
File diff suppressed because one or more lines are too long
@@ -1,146 +1,146 @@
|
||||
#ifndef GLFW_FUNCTION_TABLE_H
|
||||
#define GLFW_FUNCTION_TABLE_H
|
||||
|
||||
#include "../lib/glfw/glfw3.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef struct GLFWFunctionTable {
|
||||
GLFWcursor *(*glfwCreateCursor)(const GLFWimage *image, int xhot, int yhot);
|
||||
GLFWcursor *(*glfwCreateStandardCursor)(int shape);
|
||||
GLFWwindow *(*glfwCreateWindow)(int width, int height, const char *title,
|
||||
GLFWmonitor *monitor, GLFWwindow *share);
|
||||
void (*glfwDefaultWindowHints)(void);
|
||||
void (*glfwDestroyCursor)(GLFWcursor *cursor);
|
||||
void (*glfwDestroyWindow)(GLFWwindow *window);
|
||||
int (*glfwExtensionSupported)(const char *extension);
|
||||
void (*glfwFocusWindow)(GLFWwindow *window);
|
||||
const char *(*glfwGetClipboardString)(GLFWwindow *window);
|
||||
GLFWwindow *(*glfwGetCurrentContext)(void);
|
||||
void (*glfwGetCursorPos)(GLFWwindow *window, double *xpos, double *ypos);
|
||||
int (*glfwGetError)(const char **description);
|
||||
void (*glfwGetFrameBufferSize)(GLFWwindow *window, int *width, int *height);
|
||||
const char *(*glfwGetGamepadName)(int jid);
|
||||
int (*glfwGetGamepadState)(int jid, GLFWgamepadstate *state);
|
||||
const GLFWgammaramp *(*glfwGetGammaRamp)(GLFWmonitor *monitor);
|
||||
int (*glfwGetInputMode)(GLFWwindow *window, int mode);
|
||||
const float *(*glfwGetJoystickAxes)(int jid, int *count);
|
||||
const unsigned char *(*glfwGetJoystickButtons)(int jid, int *count);
|
||||
const char *(*glfwGetJoystickGUID)(int jid);
|
||||
const unsigned char *(*glfwGetJoystickHats)(int jid, int *count);
|
||||
const char *(*glfwGetJoystickName)(int jid);
|
||||
void *(*glfwGetJoystickUserPointer)(int jid);
|
||||
int (*glfwGetKey)(GLFWwindow *window, int key);
|
||||
const char *(*glfwGetKeyName)(int key, int scancode);
|
||||
int (*glfwGetKeyScancode)(int key);
|
||||
void (*glfwGetMonitorContentScale)(GLFWmonitor *monitor, float *xscale, float *yscale);
|
||||
const char *(*glfwGetMonitorName)(GLFWmonitor *monitor);
|
||||
void (*glfwGetMonitorPhysicalSize)(GLFWmonitor *monitor, int *widthMM, int *heightMM);
|
||||
void (*glfwGetMonitorPos)(GLFWmonitor *monitor, int *xpos, int *ypos);
|
||||
GLFWmonitor **(*glfwGetMonitors)(int *count);
|
||||
void *(*glfwGetMonitorUserPointer)(GLFWmonitor *monitor);
|
||||
void (*glfwGetMonitorWorkarea)(GLFWmonitor *monitor, int *xpos, int *ypos, int *width,
|
||||
int *height);
|
||||
int (*glfwGetMouseButton)(GLFWwindow *window, int button);
|
||||
GLFWmonitor *(*glfwGetPrimaryMonitor)(void);
|
||||
GLFWglproc (*glfwGetProcAddress)(const char *procname);
|
||||
const char **(*glfwGetRequiredInstanceExtensions)(unsigned int *count);
|
||||
double (*glfwGetTime)(void);
|
||||
unsigned long long (*glfwGetTimerFrequency)(void);
|
||||
unsigned long long (*glfwGetTimerValue)(void);
|
||||
void (*glfwGetVersion)(int *major, int *minor, int *rev);
|
||||
const char *(*glfwGetVersionString)(void);
|
||||
const GLFWvidmode *(*glfwGetVideoMode)(GLFWmonitor *monitor);
|
||||
const GLFWvidmode *(*glfwGetVideoModes)(GLFWmonitor *monitor, int *count);
|
||||
int (*glfwGetWindowAttrib)(GLFWwindow *window, int attrib);
|
||||
void (*glfwGetWindowContentScale)(GLFWwindow *window, float *xscale, float *yscale);
|
||||
void (*glfwGetWindowFrameSize)(GLFWwindow *window, int *left, int *top, int *right,
|
||||
int *bottom);
|
||||
GLFWmonitor *(*glfwGetWindowMonitor)(GLFWwindow *window);
|
||||
float (*glfwGetWindowOpacity)(GLFWwindow *window);
|
||||
void (*glfwGetWindowPos)(GLFWwindow *window, int *xpos, int *ypos);
|
||||
void (*glfwGetWindowSize)(GLFWwindow *window, int *width, int *height);
|
||||
void *(*glfwGetWindowUserPointer)(GLFWwindow *window);
|
||||
void (*glfwHideWindow)(GLFWwindow *window);
|
||||
void (*glfwIconifyWindow)(GLFWwindow *window);
|
||||
int (*glfwInit)(void);
|
||||
void (*glfwInitHint)(int hint, int value);
|
||||
int (*glfwJoystickIsGamePad)(int jid);
|
||||
int (*glfwJoystickPresent)(int jid);
|
||||
void (*glfwMakeContextCurrent)(GLFWwindow *window);
|
||||
void (*glfwMaximizeWindow)(GLFWwindow *window);
|
||||
void (*glfwPollEvents)(void);
|
||||
void (*glfwPostEmptyEvent)(void);
|
||||
int (*glfwRawMouseMotionSupported)(void);
|
||||
void (*glfwRequestWindowAttention)(GLFWwindow *window);
|
||||
void (*glfwRestoreWindow)(GLFWwindow *window);
|
||||
GLFWcharfun (*glfwSetCharCallback)(GLFWwindow *window, GLFWcharfun callback);
|
||||
GLFWcharmodsfun (*glfwSetCharModsCallback)(GLFWwindow *window, GLFWcharmodsfun callback);
|
||||
void (*glfwSetClipboardString)(GLFWwindow *window, const char *str);
|
||||
void (*glfwSetCursor)(GLFWwindow *window, GLFWcursor *cursor);
|
||||
GLFWcursorenterfun (*glfwSetCursorEnterCallback)(GLFWwindow *window,
|
||||
GLFWcursorenterfun callback);
|
||||
void (*glfwSetCursorPos)(GLFWwindow *window, double xpos, double ypos);
|
||||
GLFWcursorposfun (*glfwSetCursorPosCallback)(GLFWwindow *window, GLFWcursorposfun callback);
|
||||
GLFWdropfun (*glfwSetDropCallback)(GLFWwindow *window, GLFWdropfun callback);
|
||||
GLFWerrorfun (*glfwSetErrorCallback)(GLFWerrorfun callback);
|
||||
GLFWframebuffersizefun (*glfwSetFramebufferSizeCallback)(GLFWwindow *window,
|
||||
GLFWframebuffersizefun callback);
|
||||
void (*glfwSetGamma)(GLFWmonitor *monitor, float gamma);
|
||||
void (*glfwSetGammaRamp)(GLFWmonitor *monitor, const GLFWgammaramp *ramp);
|
||||
void (*glfwSetInputMode)(GLFWwindow *window, int mode, int value);
|
||||
GLFWjoystickfun (*glfwSetJoystickCallback)(GLFWjoystickfun callback);
|
||||
void (*glfwSetJoystickUserPointer)(int jid, void *pointer);
|
||||
GLFWkeyfun (*glfwSetKeyCallback)(GLFWwindow *window, GLFWkeyfun callback);
|
||||
GLFWmonitorfun (*glfwSetMonitorCallback)(GLFWmonitorfun callback);
|
||||
void (*glfwSetMonitorUserPointer)(GLFWmonitor *monitor, void *pointer);
|
||||
GLFWmousebuttonfun (*glfwSetMouseButtonCallback)(GLFWwindow *window,
|
||||
GLFWmousebuttonfun callback);
|
||||
GLFWscrollfun (*glfwSetScrollCallback)(GLFWwindow *window, GLFWscrollfun callback);
|
||||
void (*glfwSetTime)(double time);
|
||||
void (*glfwSetWindowAspectRatio)(GLFWwindow *window, int numer, int denom);
|
||||
void (*glfwSetWindowAttrib)(GLFWwindow *window, int attrib, int value);
|
||||
GLFWwindowclosefun (*glfwSetWindowCloseCallback)(GLFWwindow *window,
|
||||
GLFWwindowclosefun callback);
|
||||
GLFWwindowcontentscalefun (*glfwSetWindowContentScaleCallback)(
|
||||
GLFWwindow *window, GLFWwindowcontentscalefun callback);
|
||||
GLFWwindowfocusfun (*glfwSetWindowFocusCallback)(GLFWwindow *window,
|
||||
GLFWwindowfocusfun callback);
|
||||
void (*glfwSetWindowIcon)(GLFWwindow *window, int count, const GLFWimage *images);
|
||||
GLFWwindowiconifyfun (*glfwSetWindowIconifyCallback)(GLFWwindow *window,
|
||||
GLFWwindowiconifyfun callback);
|
||||
GLFWwindowmaximizefun (*glfwSetWindowMaximizeCallback)(GLFWwindow *window,
|
||||
GLFWwindowmaximizefun callback);
|
||||
void (*glfwSetWindowMonitor)(GLFWwindow *window, GLFWmonitor *monitor, int xpos, int ypos,
|
||||
int width, int height, int refreshRate);
|
||||
void (*glfwSetWindowOpacity)(GLFWwindow *window, float opacity);
|
||||
void (*glfwSetWindowPos)(GLFWwindow *window, int xpos, int ypos);
|
||||
GLFWwindowposfun (*glfwSetWindowPosCallback)(GLFWwindow *window, GLFWwindowposfun callback);
|
||||
GLFWwindowrefreshfun (*glfwSetWindowRefreshCallback)(GLFWwindow *window,
|
||||
GLFWwindowrefreshfun callback);
|
||||
void (*glfwSetWindowShouldClose)(GLFWwindow *window, int value);
|
||||
void (*glfwSetWindowSize)(GLFWwindow *window, int width, int height);
|
||||
GLFWwindowsizefun (*glfwSetWindowSizeCallback)(GLFWwindow *window,
|
||||
GLFWwindowsizefun callback);
|
||||
void (*glfwSetWindowSizeLimits)(GLFWwindow *window, int minwidth, int minheight,
|
||||
int maxwidth, int maxheight);
|
||||
void (*glfwSetWindowTitle)(GLFWwindow *window, const char *title);
|
||||
void (*glfwSetWindowUserPointer)(GLFWwindow *window, void *pointer);
|
||||
void (*glfwShowWindow)(GLFWwindow *window);
|
||||
void (*glfwSwapBuffers)(GLFWwindow *window);
|
||||
void (*glfwSwapInterval)(int interval);
|
||||
void (*glfwTerminate)(void);
|
||||
int (*glfwUpdateGamePadMappings)(const char *str);
|
||||
int (*glfwVulkanSupported)(void);
|
||||
void (*glfwWaitEvents)(void);
|
||||
void (*glfwWaitEventsTimeout)(double timeout);
|
||||
void (*glfwWindowHint)(int hint, int value);
|
||||
void (*glfwWindowHintString)(int hint, const char *value);
|
||||
int (*glfwWindowShouldClose)(GLFWwindow *window);
|
||||
} GLFWFunctionTable;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#ifndef GLFW_FUNCTION_TABLE_H
|
||||
#define GLFW_FUNCTION_TABLE_H
|
||||
|
||||
#include "../lib/glfw/glfw3.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef struct GLFWFunctionTable {
|
||||
GLFWcursor *(*glfwCreateCursor)(const GLFWimage *image, int xhot, int yhot);
|
||||
GLFWcursor *(*glfwCreateStandardCursor)(int shape);
|
||||
GLFWwindow *(*glfwCreateWindow)(int width, int height, const char *title,
|
||||
GLFWmonitor *monitor, GLFWwindow *share);
|
||||
void (*glfwDefaultWindowHints)(void);
|
||||
void (*glfwDestroyCursor)(GLFWcursor *cursor);
|
||||
void (*glfwDestroyWindow)(GLFWwindow *window);
|
||||
int (*glfwExtensionSupported)(const char *extension);
|
||||
void (*glfwFocusWindow)(GLFWwindow *window);
|
||||
const char *(*glfwGetClipboardString)(GLFWwindow *window);
|
||||
GLFWwindow *(*glfwGetCurrentContext)(void);
|
||||
void (*glfwGetCursorPos)(GLFWwindow *window, double *xpos, double *ypos);
|
||||
int (*glfwGetError)(const char **description);
|
||||
void (*glfwGetFrameBufferSize)(GLFWwindow *window, int *width, int *height);
|
||||
const char *(*glfwGetGamepadName)(int jid);
|
||||
int (*glfwGetGamepadState)(int jid, GLFWgamepadstate *state);
|
||||
const GLFWgammaramp *(*glfwGetGammaRamp)(GLFWmonitor *monitor);
|
||||
int (*glfwGetInputMode)(GLFWwindow *window, int mode);
|
||||
const float *(*glfwGetJoystickAxes)(int jid, int *count);
|
||||
const unsigned char *(*glfwGetJoystickButtons)(int jid, int *count);
|
||||
const char *(*glfwGetJoystickGUID)(int jid);
|
||||
const unsigned char *(*glfwGetJoystickHats)(int jid, int *count);
|
||||
const char *(*glfwGetJoystickName)(int jid);
|
||||
void *(*glfwGetJoystickUserPointer)(int jid);
|
||||
int (*glfwGetKey)(GLFWwindow *window, int key);
|
||||
const char *(*glfwGetKeyName)(int key, int scancode);
|
||||
int (*glfwGetKeyScancode)(int key);
|
||||
void (*glfwGetMonitorContentScale)(GLFWmonitor *monitor, float *xscale, float *yscale);
|
||||
const char *(*glfwGetMonitorName)(GLFWmonitor *monitor);
|
||||
void (*glfwGetMonitorPhysicalSize)(GLFWmonitor *monitor, int *widthMM, int *heightMM);
|
||||
void (*glfwGetMonitorPos)(GLFWmonitor *monitor, int *xpos, int *ypos);
|
||||
GLFWmonitor **(*glfwGetMonitors)(int *count);
|
||||
void *(*glfwGetMonitorUserPointer)(GLFWmonitor *monitor);
|
||||
void (*glfwGetMonitorWorkarea)(GLFWmonitor *monitor, int *xpos, int *ypos, int *width,
|
||||
int *height);
|
||||
int (*glfwGetMouseButton)(GLFWwindow *window, int button);
|
||||
GLFWmonitor *(*glfwGetPrimaryMonitor)(void);
|
||||
GLFWglproc (*glfwGetProcAddress)(const char *procname);
|
||||
const char **(*glfwGetRequiredInstanceExtensions)(unsigned int *count);
|
||||
double (*glfwGetTime)(void);
|
||||
unsigned long long (*glfwGetTimerFrequency)(void);
|
||||
unsigned long long (*glfwGetTimerValue)(void);
|
||||
void (*glfwGetVersion)(int *major, int *minor, int *rev);
|
||||
const char *(*glfwGetVersionString)(void);
|
||||
const GLFWvidmode *(*glfwGetVideoMode)(GLFWmonitor *monitor);
|
||||
const GLFWvidmode *(*glfwGetVideoModes)(GLFWmonitor *monitor, int *count);
|
||||
int (*glfwGetWindowAttrib)(GLFWwindow *window, int attrib);
|
||||
void (*glfwGetWindowContentScale)(GLFWwindow *window, float *xscale, float *yscale);
|
||||
void (*glfwGetWindowFrameSize)(GLFWwindow *window, int *left, int *top, int *right,
|
||||
int *bottom);
|
||||
GLFWmonitor *(*glfwGetWindowMonitor)(GLFWwindow *window);
|
||||
float (*glfwGetWindowOpacity)(GLFWwindow *window);
|
||||
void (*glfwGetWindowPos)(GLFWwindow *window, int *xpos, int *ypos);
|
||||
void (*glfwGetWindowSize)(GLFWwindow *window, int *width, int *height);
|
||||
void *(*glfwGetWindowUserPointer)(GLFWwindow *window);
|
||||
void (*glfwHideWindow)(GLFWwindow *window);
|
||||
void (*glfwIconifyWindow)(GLFWwindow *window);
|
||||
int (*glfwInit)(void);
|
||||
void (*glfwInitHint)(int hint, int value);
|
||||
int (*glfwJoystickIsGamePad)(int jid);
|
||||
int (*glfwJoystickPresent)(int jid);
|
||||
void (*glfwMakeContextCurrent)(GLFWwindow *window);
|
||||
void (*glfwMaximizeWindow)(GLFWwindow *window);
|
||||
void (*glfwPollEvents)(void);
|
||||
void (*glfwPostEmptyEvent)(void);
|
||||
int (*glfwRawMouseMotionSupported)(void);
|
||||
void (*glfwRequestWindowAttention)(GLFWwindow *window);
|
||||
void (*glfwRestoreWindow)(GLFWwindow *window);
|
||||
GLFWcharfun (*glfwSetCharCallback)(GLFWwindow *window, GLFWcharfun callback);
|
||||
GLFWcharmodsfun (*glfwSetCharModsCallback)(GLFWwindow *window, GLFWcharmodsfun callback);
|
||||
void (*glfwSetClipboardString)(GLFWwindow *window, const char *str);
|
||||
void (*glfwSetCursor)(GLFWwindow *window, GLFWcursor *cursor);
|
||||
GLFWcursorenterfun (*glfwSetCursorEnterCallback)(GLFWwindow *window,
|
||||
GLFWcursorenterfun callback);
|
||||
void (*glfwSetCursorPos)(GLFWwindow *window, double xpos, double ypos);
|
||||
GLFWcursorposfun (*glfwSetCursorPosCallback)(GLFWwindow *window, GLFWcursorposfun callback);
|
||||
GLFWdropfun (*glfwSetDropCallback)(GLFWwindow *window, GLFWdropfun callback);
|
||||
GLFWerrorfun (*glfwSetErrorCallback)(GLFWerrorfun callback);
|
||||
GLFWframebuffersizefun (*glfwSetFramebufferSizeCallback)(GLFWwindow *window,
|
||||
GLFWframebuffersizefun callback);
|
||||
void (*glfwSetGamma)(GLFWmonitor *monitor, float gamma);
|
||||
void (*glfwSetGammaRamp)(GLFWmonitor *monitor, const GLFWgammaramp *ramp);
|
||||
void (*glfwSetInputMode)(GLFWwindow *window, int mode, int value);
|
||||
GLFWjoystickfun (*glfwSetJoystickCallback)(GLFWjoystickfun callback);
|
||||
void (*glfwSetJoystickUserPointer)(int jid, void *pointer);
|
||||
GLFWkeyfun (*glfwSetKeyCallback)(GLFWwindow *window, GLFWkeyfun callback);
|
||||
GLFWmonitorfun (*glfwSetMonitorCallback)(GLFWmonitorfun callback);
|
||||
void (*glfwSetMonitorUserPointer)(GLFWmonitor *monitor, void *pointer);
|
||||
GLFWmousebuttonfun (*glfwSetMouseButtonCallback)(GLFWwindow *window,
|
||||
GLFWmousebuttonfun callback);
|
||||
GLFWscrollfun (*glfwSetScrollCallback)(GLFWwindow *window, GLFWscrollfun callback);
|
||||
void (*glfwSetTime)(double time);
|
||||
void (*glfwSetWindowAspectRatio)(GLFWwindow *window, int numer, int denom);
|
||||
void (*glfwSetWindowAttrib)(GLFWwindow *window, int attrib, int value);
|
||||
GLFWwindowclosefun (*glfwSetWindowCloseCallback)(GLFWwindow *window,
|
||||
GLFWwindowclosefun callback);
|
||||
GLFWwindowcontentscalefun (*glfwSetWindowContentScaleCallback)(
|
||||
GLFWwindow *window, GLFWwindowcontentscalefun callback);
|
||||
GLFWwindowfocusfun (*glfwSetWindowFocusCallback)(GLFWwindow *window,
|
||||
GLFWwindowfocusfun callback);
|
||||
void (*glfwSetWindowIcon)(GLFWwindow *window, int count, const GLFWimage *images);
|
||||
GLFWwindowiconifyfun (*glfwSetWindowIconifyCallback)(GLFWwindow *window,
|
||||
GLFWwindowiconifyfun callback);
|
||||
GLFWwindowmaximizefun (*glfwSetWindowMaximizeCallback)(GLFWwindow *window,
|
||||
GLFWwindowmaximizefun callback);
|
||||
void (*glfwSetWindowMonitor)(GLFWwindow *window, GLFWmonitor *monitor, int xpos, int ypos,
|
||||
int width, int height, int refreshRate);
|
||||
void (*glfwSetWindowOpacity)(GLFWwindow *window, float opacity);
|
||||
void (*glfwSetWindowPos)(GLFWwindow *window, int xpos, int ypos);
|
||||
GLFWwindowposfun (*glfwSetWindowPosCallback)(GLFWwindow *window, GLFWwindowposfun callback);
|
||||
GLFWwindowrefreshfun (*glfwSetWindowRefreshCallback)(GLFWwindow *window,
|
||||
GLFWwindowrefreshfun callback);
|
||||
void (*glfwSetWindowShouldClose)(GLFWwindow *window, int value);
|
||||
void (*glfwSetWindowSize)(GLFWwindow *window, int width, int height);
|
||||
GLFWwindowsizefun (*glfwSetWindowSizeCallback)(GLFWwindow *window,
|
||||
GLFWwindowsizefun callback);
|
||||
void (*glfwSetWindowSizeLimits)(GLFWwindow *window, int minwidth, int minheight,
|
||||
int maxwidth, int maxheight);
|
||||
void (*glfwSetWindowTitle)(GLFWwindow *window, const char *title);
|
||||
void (*glfwSetWindowUserPointer)(GLFWwindow *window, void *pointer);
|
||||
void (*glfwShowWindow)(GLFWwindow *window);
|
||||
void (*glfwSwapBuffers)(GLFWwindow *window);
|
||||
void (*glfwSwapInterval)(int interval);
|
||||
void (*glfwTerminate)(void);
|
||||
int (*glfwUpdateGamePadMappings)(const char *str);
|
||||
int (*glfwVulkanSupported)(void);
|
||||
void (*glfwWaitEvents)(void);
|
||||
void (*glfwWaitEventsTimeout)(double timeout);
|
||||
void (*glfwWindowHint)(int hint, int value);
|
||||
void (*glfwWindowHintString)(int hint, const char *value);
|
||||
int (*glfwWindowShouldClose)(GLFWwindow *window);
|
||||
} GLFWFunctionTable;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,310 +1,310 @@
|
||||
#ifndef __khrplatform_h_
|
||||
#define __khrplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Khronos platform-specific types and definitions.
|
||||
*
|
||||
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||
* The last semantic modification to khrplatform.h was at commit ID:
|
||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||
*
|
||||
* Adopters may modify this file to suit their platform. Adopters are
|
||||
* encouraged to submit platform specific modifications to the Khronos
|
||||
* group so that they can be included in future versions of this file.
|
||||
* Please submit changes by filing pull requests or issues on
|
||||
* the EGL Registry repository linked above.
|
||||
*
|
||||
*
|
||||
* See the Implementer's Guidelines for information about where this file
|
||||
* should be located on your system and for more details of its use:
|
||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||
*
|
||||
* This file should be included as
|
||||
* #include <KHR/khrplatform.h>
|
||||
* by Khronos client API header files that use its types and defines.
|
||||
*
|
||||
* The types in khrplatform.h should only be used to define API-specific types.
|
||||
*
|
||||
* Types defined in khrplatform.h:
|
||||
* khronos_int8_t signed 8 bit
|
||||
* khronos_uint8_t unsigned 8 bit
|
||||
* khronos_int16_t signed 16 bit
|
||||
* khronos_uint16_t unsigned 16 bit
|
||||
* khronos_int32_t signed 32 bit
|
||||
* khronos_uint32_t unsigned 32 bit
|
||||
* khronos_int64_t signed 64 bit
|
||||
* khronos_uint64_t unsigned 64 bit
|
||||
* khronos_intptr_t signed same number of bits as a pointer
|
||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||
* khronos_ssize_t signed size
|
||||
* khronos_usize_t unsigned size
|
||||
* khronos_float_t signed 32 bit floating point
|
||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||
* nanoseconds
|
||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||
* only be used as a base type when a client API's boolean type is
|
||||
* an enum. Client APIs which use an integer or other type for
|
||||
* booleans cannot use this as the base type for their boolean.
|
||||
*
|
||||
* Tokens defined in khrplatform.h:
|
||||
*
|
||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||
*
|
||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||
*
|
||||
* Calling convention macros defined in this file:
|
||||
* KHRONOS_APICALL
|
||||
* KHRONOS_APIENTRY
|
||||
* KHRONOS_APIATTRIBUTES
|
||||
*
|
||||
* These may be used in function prototypes as:
|
||||
*
|
||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||
* int arg1,
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||
#define KHRONOS_STATIC 1
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(KHRONOS_STATIC)
|
||||
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||
* header compatible with static linking. */
|
||||
#define KHRONOS_APICALL
|
||||
#elif defined(_WIN32)
|
||||
#define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined(__SYMBIAN32__)
|
||||
#define KHRONOS_APICALL IMPORT_C
|
||||
#elif defined(__ANDROID__)
|
||||
#define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||
#else
|
||||
#define KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIENTRY
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the return type of the function and precedes the function
|
||||
* name in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||
/* Win32 but not WinCE */
|
||||
#define KHRONOS_APIENTRY __stdcall
|
||||
#else
|
||||
#define KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIATTRIBUTES
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the closing parenthesis of the function prototype arguments.
|
||||
*/
|
||||
#if defined(__ARMCC_2__)
|
||||
#define KHRONOS_APIATTRIBUTES __softfp
|
||||
#else
|
||||
#define KHRONOS_APIATTRIBUTES
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* basic type definitions
|
||||
*-----------------------------------------------------------------------*/
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || \
|
||||
defined(__SCO__) || defined(__USLC__)
|
||||
|
||||
/*
|
||||
* Using <stdint.h>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
/*
|
||||
* To support platform where unsigned long cannot be used interchangeably with
|
||||
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
|
||||
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
|
||||
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
|
||||
* unsigned long long or similar (this results in different C++ name mangling).
|
||||
* To avoid changes for existing platforms, we restrict usage of intptr_t to
|
||||
* platforms where the size of a pointer is larger than the size of long.
|
||||
*/
|
||||
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
|
||||
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
|
||||
#define KHRONOS_USE_INTPTR_T
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(__VMS) || defined(__sgi)
|
||||
|
||||
/*
|
||||
* Using <inttypes.h>
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
|
||||
/*
|
||||
* Win32
|
||||
*/
|
||||
typedef __int32 khronos_int32_t;
|
||||
typedef unsigned __int32 khronos_uint32_t;
|
||||
typedef __int64 khronos_int64_t;
|
||||
typedef unsigned __int64 khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__sun__) || defined(__digital__)
|
||||
|
||||
/*
|
||||
* Sun or Digital
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#if defined(__arch64__) || defined(_LP64)
|
||||
typedef long int khronos_int64_t;
|
||||
typedef unsigned long int khronos_uint64_t;
|
||||
#else
|
||||
typedef long long int khronos_int64_t;
|
||||
typedef unsigned long long int khronos_uint64_t;
|
||||
#endif /* __arch64__ */
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif 0
|
||||
|
||||
/*
|
||||
* Hypothetical platform with no float or int64 support
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#define KHRONOS_SUPPORT_INT64 0
|
||||
#define KHRONOS_SUPPORT_FLOAT 0
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Generic fallback
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Types that are (so far) the same on all platforms
|
||||
*/
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
typedef signed short int khronos_int16_t;
|
||||
typedef unsigned short int khronos_uint16_t;
|
||||
|
||||
/*
|
||||
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||
* to be the only LLP64 architecture in current use.
|
||||
*/
|
||||
#ifdef KHRONOS_USE_INTPTR_T
|
||||
typedef intptr_t khronos_intptr_t;
|
||||
typedef uintptr_t khronos_uintptr_t;
|
||||
#elif defined(_WIN64)
|
||||
typedef signed long long int khronos_intptr_t;
|
||||
typedef unsigned long long int khronos_uintptr_t;
|
||||
#else
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64)
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_FLOAT
|
||||
/*
|
||||
* Float type
|
||||
*/
|
||||
typedef float khronos_float_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64
|
||||
/* Time types
|
||||
*
|
||||
* These types can be used to represent a time interval in nanoseconds or
|
||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||
* time the system booted). The Unadjusted System Time is an unsigned
|
||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||
* may be either signed or unsigned.
|
||||
*/
|
||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dummy value used to pad enum types to 32 bits.
|
||||
*/
|
||||
#ifndef KHRONOS_MAX_ENUM
|
||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerated boolean type
|
||||
*
|
||||
* Values other than zero should be considered to be true. Therefore
|
||||
* comparisons should not be made against KHRONOS_TRUE.
|
||||
*/
|
||||
typedef enum {
|
||||
KHRONOS_FALSE = 0,
|
||||
KHRONOS_TRUE = 1,
|
||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||
} khronos_boolean_enum_t;
|
||||
|
||||
#endif /* __khrplatform_h_ */
|
||||
#ifndef __khrplatform_h_
|
||||
#define __khrplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Khronos platform-specific types and definitions.
|
||||
*
|
||||
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||
* The last semantic modification to khrplatform.h was at commit ID:
|
||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||
*
|
||||
* Adopters may modify this file to suit their platform. Adopters are
|
||||
* encouraged to submit platform specific modifications to the Khronos
|
||||
* group so that they can be included in future versions of this file.
|
||||
* Please submit changes by filing pull requests or issues on
|
||||
* the EGL Registry repository linked above.
|
||||
*
|
||||
*
|
||||
* See the Implementer's Guidelines for information about where this file
|
||||
* should be located on your system and for more details of its use:
|
||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||
*
|
||||
* This file should be included as
|
||||
* #include <KHR/khrplatform.h>
|
||||
* by Khronos client API header files that use its types and defines.
|
||||
*
|
||||
* The types in khrplatform.h should only be used to define API-specific types.
|
||||
*
|
||||
* Types defined in khrplatform.h:
|
||||
* khronos_int8_t signed 8 bit
|
||||
* khronos_uint8_t unsigned 8 bit
|
||||
* khronos_int16_t signed 16 bit
|
||||
* khronos_uint16_t unsigned 16 bit
|
||||
* khronos_int32_t signed 32 bit
|
||||
* khronos_uint32_t unsigned 32 bit
|
||||
* khronos_int64_t signed 64 bit
|
||||
* khronos_uint64_t unsigned 64 bit
|
||||
* khronos_intptr_t signed same number of bits as a pointer
|
||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||
* khronos_ssize_t signed size
|
||||
* khronos_usize_t unsigned size
|
||||
* khronos_float_t signed 32 bit floating point
|
||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||
* nanoseconds
|
||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||
* only be used as a base type when a client API's boolean type is
|
||||
* an enum. Client APIs which use an integer or other type for
|
||||
* booleans cannot use this as the base type for their boolean.
|
||||
*
|
||||
* Tokens defined in khrplatform.h:
|
||||
*
|
||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||
*
|
||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||
*
|
||||
* Calling convention macros defined in this file:
|
||||
* KHRONOS_APICALL
|
||||
* KHRONOS_APIENTRY
|
||||
* KHRONOS_APIATTRIBUTES
|
||||
*
|
||||
* These may be used in function prototypes as:
|
||||
*
|
||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||
* int arg1,
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||
#define KHRONOS_STATIC 1
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(KHRONOS_STATIC)
|
||||
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||
* header compatible with static linking. */
|
||||
#define KHRONOS_APICALL
|
||||
#elif defined(_WIN32)
|
||||
#define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined(__SYMBIAN32__)
|
||||
#define KHRONOS_APICALL IMPORT_C
|
||||
#elif defined(__ANDROID__)
|
||||
#define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||
#else
|
||||
#define KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIENTRY
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the return type of the function and precedes the function
|
||||
* name in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||
/* Win32 but not WinCE */
|
||||
#define KHRONOS_APIENTRY __stdcall
|
||||
#else
|
||||
#define KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIATTRIBUTES
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the closing parenthesis of the function prototype arguments.
|
||||
*/
|
||||
#if defined(__ARMCC_2__)
|
||||
#define KHRONOS_APIATTRIBUTES __softfp
|
||||
#else
|
||||
#define KHRONOS_APIATTRIBUTES
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* basic type definitions
|
||||
*-----------------------------------------------------------------------*/
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || \
|
||||
defined(__SCO__) || defined(__USLC__)
|
||||
|
||||
/*
|
||||
* Using <stdint.h>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
/*
|
||||
* To support platform where unsigned long cannot be used interchangeably with
|
||||
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
|
||||
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
|
||||
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
|
||||
* unsigned long long or similar (this results in different C++ name mangling).
|
||||
* To avoid changes for existing platforms, we restrict usage of intptr_t to
|
||||
* platforms where the size of a pointer is larger than the size of long.
|
||||
*/
|
||||
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
|
||||
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
|
||||
#define KHRONOS_USE_INTPTR_T
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(__VMS) || defined(__sgi)
|
||||
|
||||
/*
|
||||
* Using <inttypes.h>
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
|
||||
/*
|
||||
* Win32
|
||||
*/
|
||||
typedef __int32 khronos_int32_t;
|
||||
typedef unsigned __int32 khronos_uint32_t;
|
||||
typedef __int64 khronos_int64_t;
|
||||
typedef unsigned __int64 khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__sun__) || defined(__digital__)
|
||||
|
||||
/*
|
||||
* Sun or Digital
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#if defined(__arch64__) || defined(_LP64)
|
||||
typedef long int khronos_int64_t;
|
||||
typedef unsigned long int khronos_uint64_t;
|
||||
#else
|
||||
typedef long long int khronos_int64_t;
|
||||
typedef unsigned long long int khronos_uint64_t;
|
||||
#endif /* __arch64__ */
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif 0
|
||||
|
||||
/*
|
||||
* Hypothetical platform with no float or int64 support
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#define KHRONOS_SUPPORT_INT64 0
|
||||
#define KHRONOS_SUPPORT_FLOAT 0
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Generic fallback
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Types that are (so far) the same on all platforms
|
||||
*/
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
typedef signed short int khronos_int16_t;
|
||||
typedef unsigned short int khronos_uint16_t;
|
||||
|
||||
/*
|
||||
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||
* to be the only LLP64 architecture in current use.
|
||||
*/
|
||||
#ifdef KHRONOS_USE_INTPTR_T
|
||||
typedef intptr_t khronos_intptr_t;
|
||||
typedef uintptr_t khronos_uintptr_t;
|
||||
#elif defined(_WIN64)
|
||||
typedef signed long long int khronos_intptr_t;
|
||||
typedef unsigned long long int khronos_uintptr_t;
|
||||
#else
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64)
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_FLOAT
|
||||
/*
|
||||
* Float type
|
||||
*/
|
||||
typedef float khronos_float_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64
|
||||
/* Time types
|
||||
*
|
||||
* These types can be used to represent a time interval in nanoseconds or
|
||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||
* time the system booted). The Unadjusted System Time is an unsigned
|
||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||
* may be either signed or unsigned.
|
||||
*/
|
||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dummy value used to pad enum types to 32 bits.
|
||||
*/
|
||||
#ifndef KHRONOS_MAX_ENUM
|
||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerated boolean type
|
||||
*
|
||||
* Values other than zero should be considered to be true. Therefore
|
||||
* comparisons should not be made against KHRONOS_TRUE.
|
||||
*/
|
||||
typedef enum {
|
||||
KHRONOS_FALSE = 0,
|
||||
KHRONOS_TRUE = 1,
|
||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||
} khronos_boolean_enum_t;
|
||||
|
||||
#endif /* __khrplatform_h_ */
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
|
||||
#ifndef SN_INTERNAL
|
||||
#define SN_INTERNAL
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define SN_DECL __cdecl
|
||||
#define SN_MAT_DECL __cdecl __forceinline
|
||||
#define SN_API __declspec(dllexport)
|
||||
#define FORCEINLINE __forceinline
|
||||
#include <windows.h>
|
||||
#elif defined(__clang__) || defined(__GNUC__)
|
||||
#define SN_DECL __attribute__((cdecl))
|
||||
#define SN_MAT_DECL __attribute__((cdecl)) __attribute__((always_inline))
|
||||
#define SN_API __attribute__((dllexport))
|
||||
#define FORCEINLINE __attribute__((always_inline))
|
||||
#else
|
||||
#define SN_API
|
||||
#define SN_DECL
|
||||
#define SN_MAT_DECL
|
||||
#define FORCEINLINE
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define SN_ALIGNAS(n) __declspec(align(n))
|
||||
#else
|
||||
#define SN_ALIGNAS(n) __attribute__((aligned(n)))
|
||||
#endif
|
||||
|
||||
#define SN_APIDEF
|
||||
|
||||
#define PRIVATE static
|
||||
#define INTERNAL extern
|
||||
|
||||
#endif //
|
||||
|
||||
#ifndef SN_INTERNAL
|
||||
#define SN_INTERNAL
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define SN_DECL __cdecl
|
||||
#define SN_MAT_DECL __cdecl __forceinline
|
||||
#define SN_API __declspec(dllexport)
|
||||
#define FORCEINLINE __forceinline
|
||||
#include <windows.h>
|
||||
#elif defined(__clang__) || defined(__GNUC__)
|
||||
#define SN_DECL __attribute__((cdecl))
|
||||
#define SN_MAT_DECL __attribute__((cdecl)) __attribute__((always_inline))
|
||||
#define SN_API __attribute__((dllexport))
|
||||
#define FORCEINLINE __attribute__((always_inline))
|
||||
#else
|
||||
#define SN_API
|
||||
#define SN_DECL
|
||||
#define SN_MAT_DECL
|
||||
#define FORCEINLINE
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define SN_ALIGNAS(n) __declspec(align(n))
|
||||
#else
|
||||
#define SN_ALIGNAS(n) __attribute__((aligned(n)))
|
||||
#endif
|
||||
|
||||
#define SN_APIDEF
|
||||
|
||||
#define PRIVATE static
|
||||
#define INTERNAL extern
|
||||
|
||||
#endif //
|
||||
|
||||
@@ -1,206 +1,206 @@
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrinsic.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// SIMDID layout helpers (see SIMDID.x86.md)
|
||||
// bits [3..0] : Root ISA
|
||||
// bits [7..4] : Manufacture (ISA-specific)
|
||||
// bits [15..8] : MainLevel (monotonic capability)
|
||||
// bits [31..16]: AVX512 Feature
|
||||
// bits [39..32]: AMX Feature
|
||||
// bits [47..40]: AVX Feature
|
||||
// bits [63..56]: uArchHi / Policy (optional)
|
||||
// -----------------------------------------------------------------------------
|
||||
#define SIMDID_SHIFT_ROOT 0
|
||||
#define SIMDID_SHIFT_MANU 4
|
||||
#define SIMDID_SHIFT_MAIN 8
|
||||
#define SIMDID_SHIFT_AVX512 16
|
||||
#define SIMDID_SHIFT_AMX 32
|
||||
#define SIMDID_SHIFT_AVX 40
|
||||
#define SIMDID_SHIFT_UARCH 56
|
||||
|
||||
#define SIMDID_MASK_ROOT 0xFULL
|
||||
#define SIMDID_MASK_MANU (0xFULL << SIMDID_SHIFT_MANU)
|
||||
#define SIMDID_MASK_MAIN (0xFFULL << SIMDID_SHIFT_MAIN)
|
||||
#define SIMDID_MASK_AVX512 (0xFFFFULL << SIMDID_SHIFT_AVX512)
|
||||
#define SIMDID_MASK_AMX (0xFFULL << SIMDID_SHIFT_AMX)
|
||||
#define SIMDID_MASK_AVX (0xFFULL << SIMDID_SHIFT_AVX)
|
||||
#define SIMDID_MASK_UARCH (0xFFULL << SIMDID_SHIFT_UARCH)
|
||||
|
||||
// Root ISA (low nibble)
|
||||
#define SIMDID_ROOT_UNKNOWN 0x0
|
||||
#define SIMDID_ROOT_X86_64 0x1
|
||||
#define SIMDID_ROOT_AARCH64 0x2
|
||||
#define SIMDID_ROOT_PPC64LE 0x3
|
||||
#define SIMDID_ROOT_APPLESILICON 0x4
|
||||
#define SIMDID_ROOT_RISCV64 0x5
|
||||
#define SIMDID_ROOT_LOONGARCH 0x6
|
||||
|
||||
// Manufacture (x86-64 mapping; other ISAs may reinterpret)
|
||||
#define SIMDID_MANU_UNKNOWN 0x0
|
||||
#define SIMDID_MANU_INTEL 0x1
|
||||
#define SIMDID_MANU_AMD 0x2
|
||||
#define SIMDID_MANU_VIA 0x3
|
||||
|
||||
// MainLevel (ordinal, shared bits 8..15; not bit-flags)
|
||||
#define SIMDID_MAIN_LVL_NONE 0x00u
|
||||
#define SIMDID_MAIN_LVL_SSE 0x01u /* SSE1..SSE4.2 */
|
||||
#define SIMDID_MAIN_LVL_AVX2 0x02u
|
||||
#define SIMDID_MAIN_LVL_AVX512 0x03u
|
||||
#define SIMDID_MAIN_LVL_AMX 0x04u
|
||||
#define SIMDID_MAIN_LVL_AVX10 0x05u
|
||||
|
||||
#ifndef SIMDID_AVX512_BASE
|
||||
#define SIMDID_AVX512_FP16 (1U << 29)
|
||||
#define SIMDID_AVX512_BF16 (1U << 28)
|
||||
#define SIMDID_AVX512_VNNI (1U << 27)
|
||||
#define SIMDID_AVX512_VBMI2 (1U << 26)
|
||||
#define SIMDID_AVX512_VBMI (1U << 25)
|
||||
#define SIMDID_AVX512_AI_RESERVED (1U << 24)
|
||||
#define SIMDID_AVX512_BASE (1U << 20)
|
||||
#define SIMDID_AVX512_IMPL_SHIFT 22
|
||||
#define SIMDID_AVX512_IMPL_MASK (0x3U << SIMDID_AVX512_IMPL_SHIFT)
|
||||
#define SIMDID_AVX512_IMPL_UNKNOWN (0x0U << SIMDID_AVX512_IMPL_SHIFT)
|
||||
#define SIMDID_AVX512_IMPL_DUAL (0x1U << SIMDID_AVX512_IMPL_SHIFT)
|
||||
#define SIMDID_AVX512_IMPL_NATIVE (0x2U << SIMDID_AVX512_IMPL_SHIFT)
|
||||
#endif
|
||||
|
||||
#ifndef SIMDID_AVX_BASE
|
||||
#define SIMDID_AVX (1ULL << 40)
|
||||
#define SIMDID_AVX2 (1ULL << 41)
|
||||
#define SIMDID_AVX_FMA (1ULL << 42)
|
||||
#define SIMDID_AVX_F16C (1ULL << 43)
|
||||
#endif
|
||||
|
||||
#ifndef SIMDID_AMX_TILE
|
||||
#define SIMDID_AMX_TILE (1ULL << 32)
|
||||
#define SIMDID_AMX_INT8 (1ULL << 33)
|
||||
#define SIMDID_AMX_BF16 (1ULL << 34)
|
||||
#endif
|
||||
|
||||
// Pack helpers (define locally to avoid missing macros when included standalone)
|
||||
#ifndef SIMDID_PACK_ROOT
|
||||
#define SIMDID_PACK_ROOT(root) (((uint64_t)(root) & 0xFULL) << SIMDID_SHIFT_ROOT)
|
||||
#define SIMDID_PACK_MANU(manu) (((uint64_t)(manu) & 0xFULL) << SIMDID_SHIFT_MANU)
|
||||
#define SIMDID_PACK_MAIN(main) (((uint64_t)(main) & 0xFFULL) << SIMDID_SHIFT_MAIN)
|
||||
#define SIMDID_PACK_AVX512(avx512_bits) \
|
||||
(((uint64_t)(avx512_bits) & 0xFFFFULL) << SIMDID_SHIFT_AVX512)
|
||||
#define SIMDID_PACK_AMX(amx_bits) (((uint64_t)(amx_bits) & 0xFFULL) << SIMDID_SHIFT_AMX)
|
||||
#define SIMDID_PACK_AVX(avx_bits) (((uint64_t)(avx_bits) & 0xFFULL) << SIMDID_SHIFT_AVX)
|
||||
#define SIMDID_PACK_UARCH(uarch_hi) (((uint64_t)(uarch_hi) & 0xFFULL) << SIMDID_SHIFT_UARCH)
|
||||
#endif
|
||||
|
||||
/* Pre-shifted helpers for convenience when constructing SIMDID */
|
||||
#define SIMDID_MAIN_ENC_NONE SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_NONE)
|
||||
#define SIMDID_MAIN_ENC_SSE SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_SSE)
|
||||
#define SIMDID_MAIN_ENC_AVX2 SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AVX2)
|
||||
#define SIMDID_MAIN_ENC_AVX512 SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AVX512)
|
||||
#define SIMDID_MAIN_ENC_AMX SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AMX)
|
||||
#define SIMDID_MAIN_ENC_AVX10 SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AVX10)
|
||||
|
||||
#pragma region matix function
|
||||
|
||||
INTERNAL void f32_normalize(VEC(float) * source, VEC(float) * target);
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, sse, , add);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, avx, , add);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, 512, , add);
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, sse, , add);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, avx, , add);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, 512, , add);
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, sse, , sub);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, avx, , sub);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, 512, , sub);
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, sse, , sub);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, avx, , sub);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, 512, , sub);
|
||||
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, sse, , transpose);
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, avx, , transpose);
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, 512, , transpose);
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, sse, , scalar_mul);
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, avx, , scalar_mul);
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, 512, , scalar_mul);
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(double, sse, , scalar_mul);
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(double, avx, , scalar_mul);
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(double, 512, , scalar_mul);
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(float, sse, , fill);
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(float, avx, , fill);
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(float, 512, , fill);
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(double, sse, , fill);
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(double, avx, , fill);
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(double, 512, , fill);
|
||||
|
||||
DECLARE_PNL_PROC_ANS(float, sse, , clear);
|
||||
DECLARE_PNL_PROC_ANS(float, avx, , clear);
|
||||
DECLARE_PNL_PROC_ANS(float, 512, , clear);
|
||||
|
||||
DECLARE_PNL_PROC_ANS(double, sse, , clear);
|
||||
DECLARE_PNL_PROC_ANS(double, avx, , clear);
|
||||
DECLARE_PNL_PROC_ANS(double, 512, , clear);
|
||||
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, sse, , quality);
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, sse, , fma);
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, avx, , fma);
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, avx, _fma, fma);
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, 512, , fma);
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, sse, , fma);
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, avx, , fma);
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, avx, _fma, fma);
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, 512, , fma);
|
||||
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(float, sse, , fma);
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(float, avx, , fma);
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(float, avx, _fma, fma);
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(float, 512, , fma);
|
||||
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(double, sse, , fma);
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(double, avx, , fma);
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(double, avx, _fma, fma);
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(double, 512, , fma);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region scaler_simd
|
||||
|
||||
INTERNAL uint64_t SN_DECL factorial_simd_sse(int n);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region dot_product
|
||||
|
||||
INTERNAL void FORCEINLINE SN_DECL dot_41_sse(MAT_KERNEL(float) const *transpose,
|
||||
__m128 const *vector, __m128 *ans);
|
||||
INTERNAL void SN_DECL dot_41_avx(MAT_KERNEL(float) const *transpose, __m128 const *vector,
|
||||
__m128 *ans);
|
||||
INTERNAL void SN_DECL dot_42_sse(MAT_KERNEL(float) const *transpose, __m128 const *vector,
|
||||
__m128 *ans);
|
||||
INTERNAL void SN_DECL dot_42_avx(MAT_KERNEL(float) const *transpose, __m128 const *vector,
|
||||
__m128 *ans);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region string
|
||||
|
||||
INTERNAL int SN_DECL city_hash_simplify_sse(byte const *str, int length);
|
||||
INTERNAL int SN_DECL index_pair_sse(short const *stram, uint32_t target, int length);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#else
|
||||
|
||||
typedef enum intrinsic_level { SIMD0 = 0 } intrinsic_level;
|
||||
|
||||
#endif
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrinsic.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// SIMDID layout helpers (see SIMDID.x86.md)
|
||||
// bits [3..0] : Root ISA
|
||||
// bits [7..4] : Manufacture (ISA-specific)
|
||||
// bits [15..8] : MainLevel (monotonic capability)
|
||||
// bits [31..16]: AVX512 Feature
|
||||
// bits [39..32]: AMX Feature
|
||||
// bits [47..40]: AVX Feature
|
||||
// bits [63..56]: uArchHi / Policy (optional)
|
||||
// -----------------------------------------------------------------------------
|
||||
#define SIMDID_SHIFT_ROOT 0
|
||||
#define SIMDID_SHIFT_MANU 4
|
||||
#define SIMDID_SHIFT_MAIN 8
|
||||
#define SIMDID_SHIFT_AVX512 16
|
||||
#define SIMDID_SHIFT_AMX 32
|
||||
#define SIMDID_SHIFT_AVX 40
|
||||
#define SIMDID_SHIFT_UARCH 56
|
||||
|
||||
#define SIMDID_MASK_ROOT 0xFULL
|
||||
#define SIMDID_MASK_MANU (0xFULL << SIMDID_SHIFT_MANU)
|
||||
#define SIMDID_MASK_MAIN (0xFFULL << SIMDID_SHIFT_MAIN)
|
||||
#define SIMDID_MASK_AVX512 (0xFFFFULL << SIMDID_SHIFT_AVX512)
|
||||
#define SIMDID_MASK_AMX (0xFFULL << SIMDID_SHIFT_AMX)
|
||||
#define SIMDID_MASK_AVX (0xFFULL << SIMDID_SHIFT_AVX)
|
||||
#define SIMDID_MASK_UARCH (0xFFULL << SIMDID_SHIFT_UARCH)
|
||||
|
||||
// Root ISA (low nibble)
|
||||
#define SIMDID_ROOT_UNKNOWN 0x0
|
||||
#define SIMDID_ROOT_X86_64 0x1
|
||||
#define SIMDID_ROOT_AARCH64 0x2
|
||||
#define SIMDID_ROOT_PPC64LE 0x3
|
||||
#define SIMDID_ROOT_APPLESILICON 0x4
|
||||
#define SIMDID_ROOT_RISCV64 0x5
|
||||
#define SIMDID_ROOT_LOONGARCH 0x6
|
||||
|
||||
// Manufacture (x86-64 mapping; other ISAs may reinterpret)
|
||||
#define SIMDID_MANU_UNKNOWN 0x0
|
||||
#define SIMDID_MANU_INTEL 0x1
|
||||
#define SIMDID_MANU_AMD 0x2
|
||||
#define SIMDID_MANU_VIA 0x3
|
||||
|
||||
// MainLevel (ordinal, shared bits 8..15; not bit-flags)
|
||||
#define SIMDID_MAIN_LVL_NONE 0x00u
|
||||
#define SIMDID_MAIN_LVL_SSE 0x01u /* SSE1..SSE4.2 */
|
||||
#define SIMDID_MAIN_LVL_AVX2 0x02u
|
||||
#define SIMDID_MAIN_LVL_AVX512 0x03u
|
||||
#define SIMDID_MAIN_LVL_AMX 0x04u
|
||||
#define SIMDID_MAIN_LVL_AVX10 0x05u
|
||||
|
||||
#ifndef SIMDID_AVX512_BASE
|
||||
#define SIMDID_AVX512_FP16 (1U << 29)
|
||||
#define SIMDID_AVX512_BF16 (1U << 28)
|
||||
#define SIMDID_AVX512_VNNI (1U << 27)
|
||||
#define SIMDID_AVX512_VBMI2 (1U << 26)
|
||||
#define SIMDID_AVX512_VBMI (1U << 25)
|
||||
#define SIMDID_AVX512_AI_RESERVED (1U << 24)
|
||||
#define SIMDID_AVX512_BASE (1U << 20)
|
||||
#define SIMDID_AVX512_IMPL_SHIFT 22
|
||||
#define SIMDID_AVX512_IMPL_MASK (0x3U << SIMDID_AVX512_IMPL_SHIFT)
|
||||
#define SIMDID_AVX512_IMPL_UNKNOWN (0x0U << SIMDID_AVX512_IMPL_SHIFT)
|
||||
#define SIMDID_AVX512_IMPL_DUAL (0x1U << SIMDID_AVX512_IMPL_SHIFT)
|
||||
#define SIMDID_AVX512_IMPL_NATIVE (0x2U << SIMDID_AVX512_IMPL_SHIFT)
|
||||
#endif
|
||||
|
||||
#ifndef SIMDID_AVX_BASE
|
||||
#define SIMDID_AVX (1ULL << 40)
|
||||
#define SIMDID_AVX2 (1ULL << 41)
|
||||
#define SIMDID_AVX_FMA (1ULL << 42)
|
||||
#define SIMDID_AVX_F16C (1ULL << 43)
|
||||
#endif
|
||||
|
||||
#ifndef SIMDID_AMX_TILE
|
||||
#define SIMDID_AMX_TILE (1ULL << 32)
|
||||
#define SIMDID_AMX_INT8 (1ULL << 33)
|
||||
#define SIMDID_AMX_BF16 (1ULL << 34)
|
||||
#endif
|
||||
|
||||
// Pack helpers (define locally to avoid missing macros when included standalone)
|
||||
#ifndef SIMDID_PACK_ROOT
|
||||
#define SIMDID_PACK_ROOT(root) (((uint64_t)(root) & 0xFULL) << SIMDID_SHIFT_ROOT)
|
||||
#define SIMDID_PACK_MANU(manu) (((uint64_t)(manu) & 0xFULL) << SIMDID_SHIFT_MANU)
|
||||
#define SIMDID_PACK_MAIN(main) (((uint64_t)(main) & 0xFFULL) << SIMDID_SHIFT_MAIN)
|
||||
#define SIMDID_PACK_AVX512(avx512_bits) \
|
||||
(((uint64_t)(avx512_bits) & 0xFFFFULL) << SIMDID_SHIFT_AVX512)
|
||||
#define SIMDID_PACK_AMX(amx_bits) (((uint64_t)(amx_bits) & 0xFFULL) << SIMDID_SHIFT_AMX)
|
||||
#define SIMDID_PACK_AVX(avx_bits) (((uint64_t)(avx_bits) & 0xFFULL) << SIMDID_SHIFT_AVX)
|
||||
#define SIMDID_PACK_UARCH(uarch_hi) (((uint64_t)(uarch_hi) & 0xFFULL) << SIMDID_SHIFT_UARCH)
|
||||
#endif
|
||||
|
||||
/* Pre-shifted helpers for convenience when constructing SIMDID */
|
||||
#define SIMDID_MAIN_ENC_NONE SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_NONE)
|
||||
#define SIMDID_MAIN_ENC_SSE SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_SSE)
|
||||
#define SIMDID_MAIN_ENC_AVX2 SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AVX2)
|
||||
#define SIMDID_MAIN_ENC_AVX512 SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AVX512)
|
||||
#define SIMDID_MAIN_ENC_AMX SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AMX)
|
||||
#define SIMDID_MAIN_ENC_AVX10 SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AVX10)
|
||||
|
||||
#pragma region matix function
|
||||
|
||||
INTERNAL void f32_normalize(VEC(float) * source, VEC(float) * target);
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, sse, , add);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, avx, , add);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, 512, , add);
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, sse, , add);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, avx, , add);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, 512, , add);
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, sse, , sub);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, avx, , sub);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, 512, , sub);
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, sse, , sub);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, avx, , sub);
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, 512, , sub);
|
||||
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, sse, , transpose);
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, avx, , transpose);
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, 512, , transpose);
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, sse, , scalar_mul);
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, avx, , scalar_mul);
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, 512, , scalar_mul);
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(double, sse, , scalar_mul);
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(double, avx, , scalar_mul);
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(double, 512, , scalar_mul);
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(float, sse, , fill);
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(float, avx, , fill);
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(float, 512, , fill);
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(double, sse, , fill);
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(double, avx, , fill);
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(double, 512, , fill);
|
||||
|
||||
DECLARE_PNL_PROC_ANS(float, sse, , clear);
|
||||
DECLARE_PNL_PROC_ANS(float, avx, , clear);
|
||||
DECLARE_PNL_PROC_ANS(float, 512, , clear);
|
||||
|
||||
DECLARE_PNL_PROC_ANS(double, sse, , clear);
|
||||
DECLARE_PNL_PROC_ANS(double, avx, , clear);
|
||||
DECLARE_PNL_PROC_ANS(double, 512, , clear);
|
||||
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, sse, , quality);
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, sse, , fma);
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, avx, , fma);
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, avx, _fma, fma);
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, 512, , fma);
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, sse, , fma);
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, avx, , fma);
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, avx, _fma, fma);
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, 512, , fma);
|
||||
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(float, sse, , fma);
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(float, avx, , fma);
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(float, avx, _fma, fma);
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(float, 512, , fma);
|
||||
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(double, sse, , fma);
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(double, avx, , fma);
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(double, avx, _fma, fma);
|
||||
DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(double, 512, , fma);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region scaler_simd
|
||||
|
||||
INTERNAL uint64_t SN_DECL factorial_simd_sse(int n);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region dot_product
|
||||
|
||||
INTERNAL void FORCEINLINE SN_DECL dot_41_sse(MAT_KERNEL(float) const *transpose,
|
||||
__m128 const *vector, __m128 *ans);
|
||||
INTERNAL void SN_DECL dot_41_avx(MAT_KERNEL(float) const *transpose, __m128 const *vector,
|
||||
__m128 *ans);
|
||||
INTERNAL void SN_DECL dot_42_sse(MAT_KERNEL(float) const *transpose, __m128 const *vector,
|
||||
__m128 *ans);
|
||||
INTERNAL void SN_DECL dot_42_avx(MAT_KERNEL(float) const *transpose, __m128 const *vector,
|
||||
__m128 *ans);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region string
|
||||
|
||||
INTERNAL int SN_DECL city_hash_simplify_sse(byte const *str, int length);
|
||||
INTERNAL int SN_DECL index_pair_sse(short const *stram, uint32_t target, int length);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#else
|
||||
|
||||
typedef enum intrinsic_level { SIMD0 = 0 } intrinsic_level;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,291 +1,291 @@
|
||||
#ifndef SSC_INTRIN
|
||||
#define SSC_INTRIN
|
||||
|
||||
#define SSC_INTRIN_HEAD
|
||||
|
||||
#include "StgSharpNative.h"
|
||||
#include "sn_matkernel.h"
|
||||
#include <immintrin.h>
|
||||
#include <smmintrin.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
#include <isa_availability.h>
|
||||
#endif
|
||||
|
||||
#define LASTTWO(x) (x & 3)
|
||||
#define LAST(x) (x & 3)
|
||||
#define get_align_begin(x) ((x + 15) & (~15))
|
||||
|
||||
#define SSE_INSERT(source, target, reset3, reset2, reset1, reset0) \
|
||||
(LASTTWO(source - 1) << 6) | (LASTTWO(target - 1) << 4) | (LAST(reset3) << 3) | \
|
||||
(LAST(reset2) << 2) | (LAST(reset1) << 1) | LAST(reset0)
|
||||
#define SSE_INSERT_SIMPLE(source, target) SSE_INSERT(source, target, 0, 0, 0, 0)
|
||||
#define M256_PERMUTE(s3, s2, s1, s0) \
|
||||
((LASTTWO(s3) << 6) | (LASTTWO(s2) << 4) | (LASTTWO(s1) << 2) | (LASTTWO(s0)))
|
||||
#define BIT_CVRT(pack, index, T) *(T *)(pack->data + index)
|
||||
#define zero_vec _mm_setzero_ps()
|
||||
#define zero_vec_256 _mm256_setzero_ps()
|
||||
|
||||
#define SPAN(T) \
|
||||
struct SPAN_T { \
|
||||
T *pointer; \
|
||||
size_t length; \
|
||||
};
|
||||
|
||||
typedef union uint64_u {
|
||||
uint64_t u64;
|
||||
uint32_t u32[2];
|
||||
} uint64_u;
|
||||
|
||||
typedef struct mat_kernel mat_kernel;
|
||||
|
||||
typedef struct mat_panel mat_panel;
|
||||
|
||||
typedef union scalar_pack {
|
||||
uint64_t data[8];
|
||||
} scalar_pack;
|
||||
|
||||
// define operation style:
|
||||
|
||||
#define PANEL_OP 1
|
||||
#define BUFFER_OP 2
|
||||
#define KERNEL_OP 3
|
||||
|
||||
#define RIGHT_ANS_PARAM 1
|
||||
#define LEFT_RIGHT_ANS_PARAM 2
|
||||
#define RIGHT_ANS_SCALAR_PARAM 3
|
||||
#define LEFT_RIGHT_ANS_SCALAR_PARAM 4
|
||||
#define ANS_SCALAR_PARAM 5
|
||||
|
||||
typedef struct matrix_op_mode {
|
||||
int16_t operation_style; /* PANEL_OP, BUFFER_OP, KERNEL_OP */
|
||||
int16_t parameter_style; /* RIGHT_ANS_PARAM, LEFT_RIGHT_ANS_PARAM, e.g. */
|
||||
} matrix_op_mode;
|
||||
|
||||
/* Mirrors StgSharp.Mathematics.Numeric.MatrixParallelTaskPackage<T> (128 bytes). */
|
||||
#define MAT_TASK(T) \
|
||||
struct { \
|
||||
MAT_KERNEL(T) * left; /* Offset 0: left matrix kernel base */ \
|
||||
MAT_KERNEL(T) * right; /* Offset 8: right matrix kernel base */ \
|
||||
MAT_KERNEL(T) * result; /* Offset 16: result matrix kernel base */ \
|
||||
int32_t element_size; /* Offset 24: sizeof(T) */ \
|
||||
int32_t reserved_ptr0; /* Offset 28: reserved/extension slot */ \
|
||||
int32_t left_prim_offset; /* Offset 32 */ \
|
||||
int32_t left_prim_stride; /* Offset 36 */ \
|
||||
int32_t left_sec_offset; /* Offset 40 */ \
|
||||
int32_t left_sec_stride; /* Offset 44 */ \
|
||||
int32_t right_prim_offset; /* Offset 48 */ \
|
||||
int32_t right_prim_stride; /* Offset 52 */ \
|
||||
int32_t right_sec_offset; /* Offset 56 */ \
|
||||
int32_t right_sec_stride; /* Offset 60 */ \
|
||||
int32_t result_prim_offset; /* Offset 64 */ \
|
||||
int32_t result_prim_stride; /* Offset 68 */ \
|
||||
int32_t result_sec_offset; /* Offset 72 */ \
|
||||
int32_t result_sec_stride; /* Offset 76 */ \
|
||||
scalar_pack *scalar; /* Offset 80 */ \
|
||||
void *compute_handle; /* Offset 88 */ \
|
||||
int32_t prim_count; /* Offset 96 */ \
|
||||
matrix_op_mode compute_mode; /* Offset 100 */ \
|
||||
int32_t sec_count; /* Offset 104 */ \
|
||||
int32_t reserved_int0; /* Offset 108 */ \
|
||||
int32_t prim_tile_offset; /* Offset 112 */ \
|
||||
int32_t sec_tile_offset; /* Offset 116 */ \
|
||||
int32_t prim_cols_in_tile; /* Offset 120 */ \
|
||||
int32_t sec_cols_in_tile; /* Offset 124 */ \
|
||||
}
|
||||
typedef struct matrix_task matrix_task;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
static_assert(sizeof(matrix_task) == 128, "matrix_parallel_task_package size mismatch");
|
||||
#elif defined(__STDC_VERSION__)
|
||||
static_assert(sizeof(MAT_TASK(float)) == 128, "matrix_parallel_task_package size mismatch");
|
||||
#endif
|
||||
|
||||
#pragma region matrix buffer operation function type
|
||||
|
||||
typedef void(SN_DECL *BUF_PROC_AS)(mat_kernel *ans, scalar_pack *scalar, int count);
|
||||
typedef void(SN_DECL *BUF_PROC_RAS)(mat_kernel *right, mat_kernel *ans, scalar_pack *scalar,
|
||||
int count);
|
||||
typedef void(SN_DECL *BUF_PROC_LRAS)(mat_kernel *left, mat_kernel *right, mat_kernel *ans,
|
||||
scalar_pack *scalar, int count);
|
||||
typedef void(SN_DECL *BUF_PROC_RA)(mat_kernel *right, mat_kernel *ans, int count);
|
||||
typedef void(SN_DECL *BUF_PROC_LRA)(mat_kernel *left, mat_kernel *right, mat_kernel *ans,
|
||||
int count);
|
||||
|
||||
#define BUF_PROC(T_type, T_arch, T_feature, T_op_name) \
|
||||
T_type##_buf_##T_op_name##_##T_arch##T_feature
|
||||
|
||||
#define DECLARE_BUF_PROC_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL BUF_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) *restrict ans, scalar_pack const *scalar, size_t count)
|
||||
#define DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL BUF_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *right, MAT_KERNEL(T_type) *restrict ans, \
|
||||
scalar_pack const *scalar, size_t count)
|
||||
#define DECLARE_BUF_PROC_LEFT_RIGHT_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL BUF_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *left, MAT_KERNEL(T_type) const *right, \
|
||||
MAT_KERNEL(T_type) *restrict ans, scalar_pack const *scalar, size_t count)
|
||||
#define DECLARE_BUF_PROC_RIGHT_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL BUF_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *right, MAT_KERNEL(T_type) *restrict ans, size_t count)
|
||||
#define DECLARE_BUF_PROC_LEFT_RIGHT_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL BUF_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *left, MAT_KERNEL(T_type) const *right, \
|
||||
MAT_KERNEL(T_type) *restrict ans, size_t count)
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region matrix panel function type
|
||||
|
||||
typedef void(SN_DECL *PANEL_PROC)(mat_panel *panel, mat_kernel *kernel, int col_length,
|
||||
int row_length, int col_index, int row_index);
|
||||
typedef void(SN_DECL *PNL_PROC_LRA)(mat_panel *left, mat_panel *right, mat_panel *ans);
|
||||
typedef void(SN_DECL *PNL_PROC_RA)(mat_panel *right, mat_panel *ans);
|
||||
typedef void(SN_DECL *PNL_PROC_LRAS)(mat_panel *left, mat_panel *right, mat_panel *ans,
|
||||
scalar_pack *scalar);
|
||||
typedef void(SN_DECL *PNL_PROC_RAS)(mat_panel *right, mat_panel *ans, scalar_pack *scalar);
|
||||
|
||||
#define PNL_PROC(T_type, T_arch, T_feature, T_op_name) \
|
||||
T_type##_pnl_##T_op_name##_##T_arch##T_feature
|
||||
#define DECLARE_PNL_PROC_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL PNL_PROC(T_type, T_arch, T_feature, \
|
||||
T_op_name)(MAT_PANEL_##T_arch##(T_type) *restrict ans)
|
||||
#define DECLARE_PNL_PROC_LEFT_RIGHT_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL PNL_PROC(T_type, T_arch, T_feature, \
|
||||
T_op_name)(MAT_PANEL_##T_arch##(T_type) const *left, \
|
||||
MAT_PANEL_##T_arch##(T_type) const *right, \
|
||||
MAT_PANEL_##T_arch##(T_type) *restrict ans)
|
||||
#define DECLARE_PNL_PROC_LEFT_RIGHT_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL PNL_PROC(T_type, T_arch, T_op_name)( \
|
||||
MAT_PANEL_##T_arch##(T_type) const *left, \
|
||||
MAT_PANEL_##T_arch##(T_type) const *right, \
|
||||
MAT_PANEL_##T_arch##(T_type) *restrict ans, scalar_pack const *scalar)
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region matrix kernel function type
|
||||
|
||||
typedef void(SN_DECL *KER_PROC_AS)(mat_kernel *ans, scalar_pack *scalar);
|
||||
typedef void(SN_DECL *KER_PROC_RA)(mat_kernel *left, mat_kernel *ans);
|
||||
typedef void(SN_DECL *KER_PROC_LRA)(mat_kernel *left, mat_kernel *right, mat_kernel *ans);
|
||||
typedef void(SN_DECL *KER_PROC_LAS)(mat_kernel *matrix, mat_kernel *ans, scalar_pack *scalar);
|
||||
|
||||
#define KER_PROC(T_type, T_arch, T_feature, T_op_name) \
|
||||
T_type##_kernel_##T_op_name##_##T_arch##T_feature
|
||||
|
||||
#define DECLARE_KER_PROC_LEFT_RIGHT_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KER_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *left, MAT_KERNEL(T_type) const *right, \
|
||||
MAT_KERNEL(T_type) *restrict ans, scalar_pack const *scalar)
|
||||
#define DECLARE_KER_PROC_RIGHT_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KER_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *right, MAT_KERNEL(T_type) *restrict ans, \
|
||||
scalar_pack const *scalar)
|
||||
#define DECLARE_KER_PROC_LEFT_RIGHT_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KER_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *left, MAT_KERNEL(T_type) const *right, \
|
||||
MAT_KERNEL(T_type) *restrict ans)
|
||||
#define DECLARE_KER_PROC_RIGHT_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KER_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *right, MAT_KERNEL(T_type) *restrict ans)
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region matrix kernel tile function type
|
||||
|
||||
typedef void(SN_DECL *KERTILE_PROC_AS)(mat_kernel *ans, scalar_pack *scalar, __m128 *enumeration);
|
||||
typedef void(SN_DECL *KERTILE_PROC_RA)(mat_kernel *left, mat_kernel *ans, __m128 *enumeration);
|
||||
typedef void(SN_DECL *KERTILE_PROC_LRA)(mat_kernel *left, mat_kernel *right, mat_kernel *ans,
|
||||
__m128 *enumeration);
|
||||
typedef void(SN_DECL *KERTILE_PROC_LAS)(mat_kernel *matrix, mat_kernel *ans, scalar_pack *scalar,
|
||||
__m128 *enumeration);
|
||||
|
||||
#define KERTILE_PROC(T_type, T_arch, T_feature, T_op_name) \
|
||||
T_type##_kernel_tile_##T_op_name##_##T_arch##T_feature
|
||||
|
||||
#define DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KERTILE_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *left, MAT_KERNEL(T_type) const *right, \
|
||||
MAT_KERNEL(T_type) *restrict ans, scalar_pack const *scalar, \
|
||||
__m128 const *enumeration)
|
||||
#define DECLARE_KERTILE_PROC_RIGHT_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KERTILE_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *right, MAT_KERNEL(T_type) *restrict ans, \
|
||||
scalar_pack const *scalar, __m128 const *enumeration)
|
||||
#define DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KERTILE_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *left, MAT_KERNEL(T_type) const *right, \
|
||||
MAT_KERNEL(T_type) *restrict ans, __m128 const *enumeration)
|
||||
#define DECLARE_KERTILE_PROC_RIGHT_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KERTILE_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *right, MAT_KERNEL(T_type) *restrict ans, \
|
||||
__m128 const *enumeration)
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region special matrix kernel operation
|
||||
|
||||
typedef void(SN_DECL *PIVOTPROC)(mat_kernel const *source, size_t col_begin, size_t col_length,
|
||||
size_t *restrict ans);
|
||||
INTERNAL void SN_DECL pivot_float(MAT_KERNEL(float) const *source, size_t col_begin,
|
||||
size_t col_length, size_t *restrict ans);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
typedef void(SN_DECL *VECTORNORMALIZEPROC)(__m128 *source, __m128 *target);
|
||||
typedef void(SN_DECL *DOTPROC)(void *transpose, __m128 *vector, __m128 *ans);
|
||||
typedef uint64_t(SN_DECL *FACTORIALROC)(int n);
|
||||
|
||||
#pragma region string
|
||||
|
||||
typedef int(SN_DECL *HASH)(byte const *str, int length);
|
||||
typedef int(SN_DECL *INDEX_PAIR)(short const *stram, uint32_t target, int length);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
typedef struct mat_intrinsic {
|
||||
BUF_PROC_LRA buffer_add;
|
||||
BUF_PROC_AS buffer_fill;
|
||||
BUF_PROC_RAS buffer_scalar_mul;
|
||||
BUF_PROC_LRA buffer_sub;
|
||||
KER_PROC_RA buffer_transpose;
|
||||
PANEL_PROC build_panel;
|
||||
PANEL_PROC clear_panel;
|
||||
PNL_PROC_LRA ker_fma;
|
||||
KERTILE_PROC_LRA ker_tile_fma;
|
||||
PIVOTPROC pivot;
|
||||
PANEL_PROC store_panel;
|
||||
|
||||
} mat_intrinsic;
|
||||
|
||||
// Mirrors C# IntrinsicContext field order so managed/unmanaged layouts stay in sync.
|
||||
typedef struct sn_intrinsic {
|
||||
HASH city_hash_simplify;
|
||||
FACTORIALROC factorial_simd;
|
||||
INDEX_PAIR index_pair;
|
||||
VECTORNORMALIZEPROC vec_f32_normalize_3;
|
||||
mat_intrinsic mat[4];
|
||||
} sn_intrinsic;
|
||||
|
||||
typedef enum elment_type { F32 = 0, F64 = 1, I32 = 2, I64 = 3 } element_type;
|
||||
|
||||
typedef enum most_advanced_instruction {
|
||||
#ifdef _MSC_VER
|
||||
SSE = __IA_SUPPORT_SSE42,
|
||||
AVX256 = __IA_SUPPORT_VECTOR256,
|
||||
AVX512 = __IA_SUPPORT_VECTOR512,
|
||||
NEON
|
||||
#else
|
||||
SSE,
|
||||
AVX256,
|
||||
AVX512,
|
||||
NEON
|
||||
#endif
|
||||
} most_advanced_instruction;
|
||||
|
||||
#include "sn_target.h"
|
||||
|
||||
#endif
|
||||
#ifndef SSC_INTRIN
|
||||
#define SSC_INTRIN
|
||||
|
||||
#define SSC_INTRIN_HEAD
|
||||
|
||||
#include "StgSharpNative.h"
|
||||
#include "sn_matkernel.h"
|
||||
#include <immintrin.h>
|
||||
#include <smmintrin.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
#include <isa_availability.h>
|
||||
#endif
|
||||
|
||||
#define LASTTWO(x) (x & 3)
|
||||
#define LAST(x) (x & 3)
|
||||
#define get_align_begin(x) ((x + 15) & (~15))
|
||||
|
||||
#define SSE_INSERT(source, target, reset3, reset2, reset1, reset0) \
|
||||
(LASTTWO(source - 1) << 6) | (LASTTWO(target - 1) << 4) | (LAST(reset3) << 3) | \
|
||||
(LAST(reset2) << 2) | (LAST(reset1) << 1) | LAST(reset0)
|
||||
#define SSE_INSERT_SIMPLE(source, target) SSE_INSERT(source, target, 0, 0, 0, 0)
|
||||
#define M256_PERMUTE(s3, s2, s1, s0) \
|
||||
((LASTTWO(s3) << 6) | (LASTTWO(s2) << 4) | (LASTTWO(s1) << 2) | (LASTTWO(s0)))
|
||||
#define BIT_CVRT(pack, index, T) *(T *)(pack->data + index)
|
||||
#define zero_vec _mm_setzero_ps()
|
||||
#define zero_vec_256 _mm256_setzero_ps()
|
||||
|
||||
#define SPAN(T) \
|
||||
struct SPAN_T { \
|
||||
T *pointer; \
|
||||
size_t length; \
|
||||
};
|
||||
|
||||
typedef union uint64_u {
|
||||
uint64_t u64;
|
||||
uint32_t u32[2];
|
||||
} uint64_u;
|
||||
|
||||
typedef struct mat_kernel mat_kernel;
|
||||
|
||||
typedef struct mat_panel mat_panel;
|
||||
|
||||
typedef union scalar_pack {
|
||||
uint64_t data[8];
|
||||
} scalar_pack;
|
||||
|
||||
// define operation style:
|
||||
|
||||
#define PANEL_OP 1
|
||||
#define BUFFER_OP 2
|
||||
#define KERNEL_OP 3
|
||||
|
||||
#define RIGHT_ANS_PARAM 1
|
||||
#define LEFT_RIGHT_ANS_PARAM 2
|
||||
#define RIGHT_ANS_SCALAR_PARAM 3
|
||||
#define LEFT_RIGHT_ANS_SCALAR_PARAM 4
|
||||
#define ANS_SCALAR_PARAM 5
|
||||
|
||||
typedef struct matrix_op_mode {
|
||||
int16_t operation_style; /* PANEL_OP, BUFFER_OP, KERNEL_OP */
|
||||
int16_t parameter_style; /* RIGHT_ANS_PARAM, LEFT_RIGHT_ANS_PARAM, e.g. */
|
||||
} matrix_op_mode;
|
||||
|
||||
/* Mirrors StgSharp.Mathematics.Numeric.MatrixParallelTaskPackage<T> (128 bytes). */
|
||||
#define MAT_TASK(T) \
|
||||
struct { \
|
||||
MAT_KERNEL(T) * left; /* Offset 0: left matrix kernel base */ \
|
||||
MAT_KERNEL(T) * right; /* Offset 8: right matrix kernel base */ \
|
||||
MAT_KERNEL(T) * result; /* Offset 16: result matrix kernel base */ \
|
||||
int32_t element_size; /* Offset 24: sizeof(T) */ \
|
||||
int32_t reserved_ptr0; /* Offset 28: reserved/extension slot */ \
|
||||
int32_t left_prim_offset; /* Offset 32 */ \
|
||||
int32_t left_prim_stride; /* Offset 36 */ \
|
||||
int32_t left_sec_offset; /* Offset 40 */ \
|
||||
int32_t left_sec_stride; /* Offset 44 */ \
|
||||
int32_t right_prim_offset; /* Offset 48 */ \
|
||||
int32_t right_prim_stride; /* Offset 52 */ \
|
||||
int32_t right_sec_offset; /* Offset 56 */ \
|
||||
int32_t right_sec_stride; /* Offset 60 */ \
|
||||
int32_t result_prim_offset; /* Offset 64 */ \
|
||||
int32_t result_prim_stride; /* Offset 68 */ \
|
||||
int32_t result_sec_offset; /* Offset 72 */ \
|
||||
int32_t result_sec_stride; /* Offset 76 */ \
|
||||
scalar_pack *scalar; /* Offset 80 */ \
|
||||
void *compute_handle; /* Offset 88 */ \
|
||||
int32_t prim_count; /* Offset 96 */ \
|
||||
matrix_op_mode compute_mode; /* Offset 100 */ \
|
||||
int32_t sec_count; /* Offset 104 */ \
|
||||
int32_t reserved_int0; /* Offset 108 */ \
|
||||
int32_t prim_tile_offset; /* Offset 112 */ \
|
||||
int32_t sec_tile_offset; /* Offset 116 */ \
|
||||
int32_t prim_cols_in_tile; /* Offset 120 */ \
|
||||
int32_t sec_cols_in_tile; /* Offset 124 */ \
|
||||
}
|
||||
typedef struct matrix_task matrix_task;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
static_assert(sizeof(matrix_task) == 128, "matrix_parallel_task_package size mismatch");
|
||||
#elif defined(__STDC_VERSION__)
|
||||
static_assert(sizeof(MAT_TASK(float)) == 128, "matrix_parallel_task_package size mismatch");
|
||||
#endif
|
||||
|
||||
#pragma region matrix buffer operation function type
|
||||
|
||||
typedef void(SN_DECL *BUF_PROC_AS)(mat_kernel *ans, scalar_pack *scalar, int count);
|
||||
typedef void(SN_DECL *BUF_PROC_RAS)(mat_kernel *right, mat_kernel *ans, scalar_pack *scalar,
|
||||
int count);
|
||||
typedef void(SN_DECL *BUF_PROC_LRAS)(mat_kernel *left, mat_kernel *right, mat_kernel *ans,
|
||||
scalar_pack *scalar, int count);
|
||||
typedef void(SN_DECL *BUF_PROC_RA)(mat_kernel *right, mat_kernel *ans, int count);
|
||||
typedef void(SN_DECL *BUF_PROC_LRA)(mat_kernel *left, mat_kernel *right, mat_kernel *ans,
|
||||
int count);
|
||||
|
||||
#define BUF_PROC(T_type, T_arch, T_feature, T_op_name) \
|
||||
T_type##_buf_##T_op_name##_##T_arch##T_feature
|
||||
|
||||
#define DECLARE_BUF_PROC_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL BUF_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) *restrict ans, scalar_pack const *scalar, size_t count)
|
||||
#define DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL BUF_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *right, MAT_KERNEL(T_type) *restrict ans, \
|
||||
scalar_pack const *scalar, size_t count)
|
||||
#define DECLARE_BUF_PROC_LEFT_RIGHT_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL BUF_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *left, MAT_KERNEL(T_type) const *right, \
|
||||
MAT_KERNEL(T_type) *restrict ans, scalar_pack const *scalar, size_t count)
|
||||
#define DECLARE_BUF_PROC_RIGHT_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL BUF_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *right, MAT_KERNEL(T_type) *restrict ans, size_t count)
|
||||
#define DECLARE_BUF_PROC_LEFT_RIGHT_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL BUF_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *left, MAT_KERNEL(T_type) const *right, \
|
||||
MAT_KERNEL(T_type) *restrict ans, size_t count)
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region matrix panel function type
|
||||
|
||||
typedef void(SN_DECL *PANEL_PROC)(mat_panel *panel, mat_kernel *kernel, int col_length,
|
||||
int row_length, int col_index, int row_index);
|
||||
typedef void(SN_DECL *PNL_PROC_LRA)(mat_panel *left, mat_panel *right, mat_panel *ans);
|
||||
typedef void(SN_DECL *PNL_PROC_RA)(mat_panel *right, mat_panel *ans);
|
||||
typedef void(SN_DECL *PNL_PROC_LRAS)(mat_panel *left, mat_panel *right, mat_panel *ans,
|
||||
scalar_pack *scalar);
|
||||
typedef void(SN_DECL *PNL_PROC_RAS)(mat_panel *right, mat_panel *ans, scalar_pack *scalar);
|
||||
|
||||
#define PNL_PROC(T_type, T_arch, T_feature, T_op_name) \
|
||||
T_type##_pnl_##T_op_name##_##T_arch##T_feature
|
||||
#define DECLARE_PNL_PROC_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL PNL_PROC(T_type, T_arch, T_feature, \
|
||||
T_op_name)(MAT_PANEL_##T_arch##(T_type) *restrict ans)
|
||||
#define DECLARE_PNL_PROC_LEFT_RIGHT_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL PNL_PROC(T_type, T_arch, T_feature, \
|
||||
T_op_name)(MAT_PANEL_##T_arch##(T_type) const *left, \
|
||||
MAT_PANEL_##T_arch##(T_type) const *right, \
|
||||
MAT_PANEL_##T_arch##(T_type) *restrict ans)
|
||||
#define DECLARE_PNL_PROC_LEFT_RIGHT_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL PNL_PROC(T_type, T_arch, T_op_name)( \
|
||||
MAT_PANEL_##T_arch##(T_type) const *left, \
|
||||
MAT_PANEL_##T_arch##(T_type) const *right, \
|
||||
MAT_PANEL_##T_arch##(T_type) *restrict ans, scalar_pack const *scalar)
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region matrix kernel function type
|
||||
|
||||
typedef void(SN_DECL *KER_PROC_AS)(mat_kernel *ans, scalar_pack *scalar);
|
||||
typedef void(SN_DECL *KER_PROC_RA)(mat_kernel *left, mat_kernel *ans);
|
||||
typedef void(SN_DECL *KER_PROC_LRA)(mat_kernel *left, mat_kernel *right, mat_kernel *ans);
|
||||
typedef void(SN_DECL *KER_PROC_LAS)(mat_kernel *matrix, mat_kernel *ans, scalar_pack *scalar);
|
||||
|
||||
#define KER_PROC(T_type, T_arch, T_feature, T_op_name) \
|
||||
T_type##_kernel_##T_op_name##_##T_arch##T_feature
|
||||
|
||||
#define DECLARE_KER_PROC_LEFT_RIGHT_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KER_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *left, MAT_KERNEL(T_type) const *right, \
|
||||
MAT_KERNEL(T_type) *restrict ans, scalar_pack const *scalar)
|
||||
#define DECLARE_KER_PROC_RIGHT_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KER_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *right, MAT_KERNEL(T_type) *restrict ans, \
|
||||
scalar_pack const *scalar)
|
||||
#define DECLARE_KER_PROC_LEFT_RIGHT_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KER_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *left, MAT_KERNEL(T_type) const *right, \
|
||||
MAT_KERNEL(T_type) *restrict ans)
|
||||
#define DECLARE_KER_PROC_RIGHT_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KER_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *right, MAT_KERNEL(T_type) *restrict ans)
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region matrix kernel tile function type
|
||||
|
||||
typedef void(SN_DECL *KERTILE_PROC_AS)(mat_kernel *ans, scalar_pack *scalar, __m128 *enumeration);
|
||||
typedef void(SN_DECL *KERTILE_PROC_RA)(mat_kernel *left, mat_kernel *ans, __m128 *enumeration);
|
||||
typedef void(SN_DECL *KERTILE_PROC_LRA)(mat_kernel *left, mat_kernel *right, mat_kernel *ans,
|
||||
__m128 *enumeration);
|
||||
typedef void(SN_DECL *KERTILE_PROC_LAS)(mat_kernel *matrix, mat_kernel *ans, scalar_pack *scalar,
|
||||
__m128 *enumeration);
|
||||
|
||||
#define KERTILE_PROC(T_type, T_arch, T_feature, T_op_name) \
|
||||
T_type##_kernel_tile_##T_op_name##_##T_arch##T_feature
|
||||
|
||||
#define DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KERTILE_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *left, MAT_KERNEL(T_type) const *right, \
|
||||
MAT_KERNEL(T_type) *restrict ans, scalar_pack const *scalar, \
|
||||
__m128 const *enumeration)
|
||||
#define DECLARE_KERTILE_PROC_RIGHT_ANS_SCALAR(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KERTILE_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *right, MAT_KERNEL(T_type) *restrict ans, \
|
||||
scalar_pack const *scalar, __m128 const *enumeration)
|
||||
#define DECLARE_KERTILE_PROC_LEFT_RIGHT_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KERTILE_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *left, MAT_KERNEL(T_type) const *right, \
|
||||
MAT_KERNEL(T_type) *restrict ans, __m128 const *enumeration)
|
||||
#define DECLARE_KERTILE_PROC_RIGHT_ANS(T_type, T_arch, T_feature, T_op_name) \
|
||||
INTERNAL void SN_DECL KERTILE_PROC(T_type, T_arch, T_feature, T_op_name)( \
|
||||
MAT_KERNEL(T_type) const *right, MAT_KERNEL(T_type) *restrict ans, \
|
||||
__m128 const *enumeration)
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region special matrix kernel operation
|
||||
|
||||
typedef void(SN_DECL *PIVOTPROC)(mat_kernel const *source, size_t col_begin, size_t col_length,
|
||||
size_t *restrict ans);
|
||||
INTERNAL void SN_DECL pivot_float(MAT_KERNEL(float) const *source, size_t col_begin,
|
||||
size_t col_length, size_t *restrict ans);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
typedef void(SN_DECL *VECTORNORMALIZEPROC)(__m128 *source, __m128 *target);
|
||||
typedef void(SN_DECL *DOTPROC)(void *transpose, __m128 *vector, __m128 *ans);
|
||||
typedef uint64_t(SN_DECL *FACTORIALROC)(int n);
|
||||
|
||||
#pragma region string
|
||||
|
||||
typedef int(SN_DECL *HASH)(byte const *str, int length);
|
||||
typedef int(SN_DECL *INDEX_PAIR)(short const *stram, uint32_t target, int length);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
typedef struct mat_intrinsic {
|
||||
BUF_PROC_LRA buffer_add;
|
||||
BUF_PROC_AS buffer_fill;
|
||||
BUF_PROC_RAS buffer_scalar_mul;
|
||||
BUF_PROC_LRA buffer_sub;
|
||||
KER_PROC_RA buffer_transpose;
|
||||
PANEL_PROC build_panel;
|
||||
PANEL_PROC clear_panel;
|
||||
PNL_PROC_LRA ker_fma;
|
||||
KERTILE_PROC_LRA ker_tile_fma;
|
||||
PIVOTPROC pivot;
|
||||
PANEL_PROC store_panel;
|
||||
|
||||
} mat_intrinsic;
|
||||
|
||||
// Mirrors C# IntrinsicContext field order so managed/unmanaged layouts stay in sync.
|
||||
typedef struct sn_intrinsic {
|
||||
HASH city_hash_simplify;
|
||||
FACTORIALROC factorial_simd;
|
||||
INDEX_PAIR index_pair;
|
||||
VECTORNORMALIZEPROC vec_f32_normalize_3;
|
||||
mat_intrinsic mat[4];
|
||||
} sn_intrinsic;
|
||||
|
||||
typedef enum elment_type { F32 = 0, F64 = 1, I32 = 2, I64 = 3 } element_type;
|
||||
|
||||
typedef enum most_advanced_instruction {
|
||||
#ifdef _MSC_VER
|
||||
SSE = __IA_SUPPORT_SSE42,
|
||||
AVX256 = __IA_SUPPORT_VECTOR256,
|
||||
AVX512 = __IA_SUPPORT_VECTOR512,
|
||||
NEON
|
||||
#else
|
||||
SSE,
|
||||
AVX256,
|
||||
AVX512,
|
||||
NEON
|
||||
#endif
|
||||
} most_advanced_instruction;
|
||||
|
||||
#include "sn_target.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,140 +1,140 @@
|
||||
#ifndef SN_MATKERNEL
|
||||
#define SN_MATKERNEL
|
||||
|
||||
#include <immintrin.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sn_internal.h"
|
||||
|
||||
/* Kernel storage unions for a fixed 4x4 block. */
|
||||
#define ELEMENTSIZE(T) sizeof(T)
|
||||
#define XMMCOUNT(T) (sizeof(T))
|
||||
#define YMMCOUNT(T) (sizeof(T) / 2)
|
||||
#define ZMMCOUNT(T) (sizeof(T) / 4)
|
||||
|
||||
#define MAT_KERNEL(T) \
|
||||
union /* MAT_KERNEL_##T## /**/ { \
|
||||
__m128 f32_x[XMMCOUNT(T)]; \
|
||||
__m256 f32_y[YMMCOUNT(T)]; \
|
||||
__m512 f32_z[ZMMCOUNT(T)]; \
|
||||
\
|
||||
__m128d f64_x[XMMCOUNT(T)]; \
|
||||
__m256d f64_y[YMMCOUNT(T)]; \
|
||||
__m512d f64_z[ZMMCOUNT(T)]; \
|
||||
T m[4][4]; \
|
||||
}
|
||||
|
||||
#define VEC(T) \
|
||||
union { \
|
||||
__m128 f32_x[XMMCOUNT(T) / 4]; \
|
||||
__m256 f32_y[YMMCOUNT(T) / 4]; \
|
||||
__m512 f32_z[ZMMCOUNT(T) / 4]; \
|
||||
\
|
||||
__m128d f64_x[XMMCOUNT(T) / 4]; \
|
||||
__m256d f64_y[YMMCOUNT(T) / 4]; \
|
||||
__m512d f64_z[ZMMCOUNT(T) / 4]; \
|
||||
T v[4]; \
|
||||
}
|
||||
|
||||
/* Provide a named alias for the zero kernel type to ensure consistent linkage in C++. */
|
||||
typedef MAT_KERNEL(uint64_t) sn_zero_kernel_u64;
|
||||
|
||||
/* Helpers (all compile-time): */
|
||||
#define SN_LANES(T_VEC, T) (sizeof(T_VEC) / sizeof(T))
|
||||
#define SN_MAX(a, b) (((a)) > ((b)) ? (a) : (b))
|
||||
#define SN_CEIL_DIV(a, b) (((a) + (b) - 1) / (b))
|
||||
#define SN_BITS(x) ((int)(sizeof(x) * 8))
|
||||
#define PANEL_MINQ(T_VEC, T) SN_MAX(4, SN_MAX(SN_BITS(T_VEC) / 64, SN_BITS(T_VEC) / SN_BITS(T)))
|
||||
|
||||
/* Panel geometry helpers (all compile-time): */
|
||||
#define PANEL_Q(T, T_VEC, MINQ) SN_MAX(SN_LANES(T_VEC, T), (MINQ))
|
||||
#define PANEL_CHUNKS(T, T_VEC, MINQ) SN_CEIL_DIV(PANEL_Q(T, T_VEC, MINQ), SN_LANES(T_VEC, T))
|
||||
|
||||
/*
|
||||
Column-major square panel with minimum side Q:
|
||||
- Let R = lanes per vector = sizeof(T_VEC)/sizeof(T).
|
||||
- Side length Q = max(R, MINQ) to enforce the requested minimum extent.
|
||||
- Each column is stored contiguously via CH = ceil(Q/R) vector chunks.
|
||||
- Memory layout:
|
||||
vec[col][chunk] is a T_VEC holding up to R scalars of column 'col'
|
||||
spanning rows chunk*R .. chunk*R + (R - 1).
|
||||
flat[] mirrors the same column-major order (column stride = Q).
|
||||
- SIMD view remains integer-typed; cast inside micro-kernels to the
|
||||
appropriate floating-point/integer vector type on demand.
|
||||
*/
|
||||
#define MAT_PANEL_SQ_MIN_NOALIGN(T, T_VEC, MINQ) \
|
||||
union { \
|
||||
T_VEC vec[PANEL_Q(T, T_VEC, MINQ)][PANEL_CHUNKS(T, T_VEC, MINQ)]; \
|
||||
T flat[PANEL_Q(T, T_VEC, MINQ) * PANEL_Q(T, T_VEC, MINQ)]; \
|
||||
}
|
||||
|
||||
/* ISA presets with minimum square side:
|
||||
- SSE : MINQ=4 (avoid 2x2 for double)
|
||||
- AVX2 : MINQ computed as max(4, vector_bits/64, vector_bits/element_bits)
|
||||
- AVX-512: same rule (float/i32 naturally expand to 16)
|
||||
*/
|
||||
|
||||
/* SSE panel layout: column-major buffer holding 4 logical columns with MINQ=4.
|
||||
Columns: each column packs up to four scalars so ALIGN equals sizeof(__m128).
|
||||
Alignment: every column boundary lands on a 16-byte multiple for XMM loads. */
|
||||
#define MAT_PANEL_sse(T) SN_ALIGNAS(16) MAT_PANEL_SQ_MIN_NOALIGN(T, __m128, PANEL_MINQ(__m128, T))
|
||||
/* AVX2 panel layout: column-major buffer holding 8 logical columns with MINQ per PANEL_MINQ.
|
||||
Columns: each column stores up to lanes elements via contiguous chunks.
|
||||
Alignment: column starts are 32-byte aligned so AVX2 loads/stores remain contiguous. */
|
||||
#define MAT_PANEL_avx(T) SN_ALIGNAS(32) MAT_PANEL_SQ_MIN_NOALIGN(T, __m256, PANEL_MINQ(__m256, T))
|
||||
/* AVX2/FMA panel layout shares the same geometry as AVX2. */
|
||||
#define MAT_PANEL_avx_fma(T) \
|
||||
SN_ALIGNAS(32) MAT_PANEL_SQ_MIN_NOALIGN(T, __m256, PANEL_MINQ(__m256, T))
|
||||
/* AVX-512 panel layout: column-major buffer holding 8 or more columns depending on T.
|
||||
Columns: each column expands to ceil(Q/lanes) ZMM chunks.
|
||||
Alignment: column starts sit on 64-byte boundaries to match AVX-512 streaming access. */
|
||||
#define MAT_PANEL_512(T) SN_ALIGNAS(64) MAT_PANEL_SQ_MIN_NOALIGN(T, __m512, PANEL_MINQ(__m512, T))
|
||||
|
||||
/* Global zero kernel declaration (defined in dllmain.c), aligned to 64 bytes */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern __declspec(align(64)) sn_zero_kernel_u64 SN_ZERO_KERNEL;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Access helpers (all compile-time friendly):
|
||||
Given Q = PANEL_Q(...), CH = PANEL_CHUNKS(...), R = lanes per vector:
|
||||
- Column c occupies vec[c][0..CH-1].
|
||||
- Row r inside column c is located at vec[c][r / R] with lane (r % R).
|
||||
*/
|
||||
#define PANEL_COL_VEC(panel_obj, c, chunk) ((panel_obj).vec[(int)(c)][(int)(chunk)])
|
||||
/* Scalar flat index helper for column-major addressing */
|
||||
#define PANEL_ELEM(panel_obj, T, T_VEC, MINQ, r, c) \
|
||||
((panel_obj).flat[(int)(c) * PANEL_Q(T, T_VEC, MINQ) + (int)(r)])
|
||||
|
||||
/* API macros */
|
||||
#define BUILD_PANEL(arch, element) build_panel_##arch##_##element
|
||||
#define STORE_PANEL(arch, element) store_panel_##arch##_##element
|
||||
|
||||
#define DECLARE_BUILD_PANEL(arch, element) \
|
||||
INTERNAL void SN_DECL BUILD_PANEL(arch, element)( \
|
||||
MAT_PANEL_##arch(element) *restrict panel, \
|
||||
MAT_KERNEL(element) const *const matrix, int col_length, int row_length, \
|
||||
int col_index, int row_index)
|
||||
#define DECLARE_STORE_PANEL(arch, element) \
|
||||
INTERNAL void SN_DECL STORE_PANEL(arch, element)(MAT_PANEL_##arch(element) \
|
||||
const *const panel, \
|
||||
MAT_KERNEL(element) *restrict matrix, \
|
||||
int col_length, int row_length, \
|
||||
int col_index, int row_index)
|
||||
|
||||
/* Declarations for AVX float variant */
|
||||
DECLARE_BUILD_PANEL(avx, float);
|
||||
DECLARE_BUILD_PANEL(512, float);
|
||||
|
||||
DECLARE_STORE_PANEL(avx, float);
|
||||
DECLARE_STORE_PANEL(512, float);
|
||||
DECLARE_STORE_PANEL(512, float);
|
||||
|
||||
DECLARE_BUILD_PANEL(512, double);
|
||||
|
||||
DECLARE_STORE_PANEL(512, double);
|
||||
|
||||
#endif /* SN_MATKERNEL */
|
||||
#ifndef SN_MATKERNEL
|
||||
#define SN_MATKERNEL
|
||||
|
||||
#include <immintrin.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sn_internal.h"
|
||||
|
||||
/* Kernel storage unions for a fixed 4x4 block. */
|
||||
#define ELEMENTSIZE(T) sizeof(T)
|
||||
#define XMMCOUNT(T) (sizeof(T))
|
||||
#define YMMCOUNT(T) (sizeof(T) / 2)
|
||||
#define ZMMCOUNT(T) (sizeof(T) / 4)
|
||||
|
||||
#define MAT_KERNEL(T) \
|
||||
union /* MAT_KERNEL_##T## /**/ { \
|
||||
__m128 f32_x[XMMCOUNT(T)]; \
|
||||
__m256 f32_y[YMMCOUNT(T)]; \
|
||||
__m512 f32_z[ZMMCOUNT(T)]; \
|
||||
\
|
||||
__m128d f64_x[XMMCOUNT(T)]; \
|
||||
__m256d f64_y[YMMCOUNT(T)]; \
|
||||
__m512d f64_z[ZMMCOUNT(T)]; \
|
||||
T m[4][4]; \
|
||||
}
|
||||
|
||||
#define VEC(T) \
|
||||
union { \
|
||||
__m128 f32_x[XMMCOUNT(T) / 4]; \
|
||||
__m256 f32_y[YMMCOUNT(T) / 4]; \
|
||||
__m512 f32_z[ZMMCOUNT(T) / 4]; \
|
||||
\
|
||||
__m128d f64_x[XMMCOUNT(T) / 4]; \
|
||||
__m256d f64_y[YMMCOUNT(T) / 4]; \
|
||||
__m512d f64_z[ZMMCOUNT(T) / 4]; \
|
||||
T v[4]; \
|
||||
}
|
||||
|
||||
/* Provide a named alias for the zero kernel type to ensure consistent linkage in C++. */
|
||||
typedef MAT_KERNEL(uint64_t) sn_zero_kernel_u64;
|
||||
|
||||
/* Helpers (all compile-time): */
|
||||
#define SN_LANES(T_VEC, T) (sizeof(T_VEC) / sizeof(T))
|
||||
#define SN_MAX(a, b) (((a)) > ((b)) ? (a) : (b))
|
||||
#define SN_CEIL_DIV(a, b) (((a) + (b) - 1) / (b))
|
||||
#define SN_BITS(x) ((int)(sizeof(x) * 8))
|
||||
#define PANEL_MINQ(T_VEC, T) SN_MAX(4, SN_MAX(SN_BITS(T_VEC) / 64, SN_BITS(T_VEC) / SN_BITS(T)))
|
||||
|
||||
/* Panel geometry helpers (all compile-time): */
|
||||
#define PANEL_Q(T, T_VEC, MINQ) SN_MAX(SN_LANES(T_VEC, T), (MINQ))
|
||||
#define PANEL_CHUNKS(T, T_VEC, MINQ) SN_CEIL_DIV(PANEL_Q(T, T_VEC, MINQ), SN_LANES(T_VEC, T))
|
||||
|
||||
/*
|
||||
Column-major square panel with minimum side Q:
|
||||
- Let R = lanes per vector = sizeof(T_VEC)/sizeof(T).
|
||||
- Side length Q = max(R, MINQ) to enforce the requested minimum extent.
|
||||
- Each column is stored contiguously via CH = ceil(Q/R) vector chunks.
|
||||
- Memory layout:
|
||||
vec[col][chunk] is a T_VEC holding up to R scalars of column 'col'
|
||||
spanning rows chunk*R .. chunk*R + (R - 1).
|
||||
flat[] mirrors the same column-major order (column stride = Q).
|
||||
- SIMD view remains integer-typed; cast inside micro-kernels to the
|
||||
appropriate floating-point/integer vector type on demand.
|
||||
*/
|
||||
#define MAT_PANEL_SQ_MIN_NOALIGN(T, T_VEC, MINQ) \
|
||||
union { \
|
||||
T_VEC vec[PANEL_Q(T, T_VEC, MINQ)][PANEL_CHUNKS(T, T_VEC, MINQ)]; \
|
||||
T flat[PANEL_Q(T, T_VEC, MINQ) * PANEL_Q(T, T_VEC, MINQ)]; \
|
||||
}
|
||||
|
||||
/* ISA presets with minimum square side:
|
||||
- SSE : MINQ=4 (avoid 2x2 for double)
|
||||
- AVX2 : MINQ computed as max(4, vector_bits/64, vector_bits/element_bits)
|
||||
- AVX-512: same rule (float/i32 naturally expand to 16)
|
||||
*/
|
||||
|
||||
/* SSE panel layout: column-major buffer holding 4 logical columns with MINQ=4.
|
||||
Columns: each column packs up to four scalars so ALIGN equals sizeof(__m128).
|
||||
Alignment: every column boundary lands on a 16-byte multiple for XMM loads. */
|
||||
#define MAT_PANEL_sse(T) SN_ALIGNAS(16) MAT_PANEL_SQ_MIN_NOALIGN(T, __m128, PANEL_MINQ(__m128, T))
|
||||
/* AVX2 panel layout: column-major buffer holding 8 logical columns with MINQ per PANEL_MINQ.
|
||||
Columns: each column stores up to lanes elements via contiguous chunks.
|
||||
Alignment: column starts are 32-byte aligned so AVX2 loads/stores remain contiguous. */
|
||||
#define MAT_PANEL_avx(T) SN_ALIGNAS(32) MAT_PANEL_SQ_MIN_NOALIGN(T, __m256, PANEL_MINQ(__m256, T))
|
||||
/* AVX2/FMA panel layout shares the same geometry as AVX2. */
|
||||
#define MAT_PANEL_avx_fma(T) \
|
||||
SN_ALIGNAS(32) MAT_PANEL_SQ_MIN_NOALIGN(T, __m256, PANEL_MINQ(__m256, T))
|
||||
/* AVX-512 panel layout: column-major buffer holding 8 or more columns depending on T.
|
||||
Columns: each column expands to ceil(Q/lanes) ZMM chunks.
|
||||
Alignment: column starts sit on 64-byte boundaries to match AVX-512 streaming access. */
|
||||
#define MAT_PANEL_512(T) SN_ALIGNAS(64) MAT_PANEL_SQ_MIN_NOALIGN(T, __m512, PANEL_MINQ(__m512, T))
|
||||
|
||||
/* Global zero kernel declaration (defined in dllmain.c), aligned to 64 bytes */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern __declspec(align(64)) sn_zero_kernel_u64 SN_ZERO_KERNEL;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Access helpers (all compile-time friendly):
|
||||
Given Q = PANEL_Q(...), CH = PANEL_CHUNKS(...), R = lanes per vector:
|
||||
- Column c occupies vec[c][0..CH-1].
|
||||
- Row r inside column c is located at vec[c][r / R] with lane (r % R).
|
||||
*/
|
||||
#define PANEL_COL_VEC(panel_obj, c, chunk) ((panel_obj).vec[(int)(c)][(int)(chunk)])
|
||||
/* Scalar flat index helper for column-major addressing */
|
||||
#define PANEL_ELEM(panel_obj, T, T_VEC, MINQ, r, c) \
|
||||
((panel_obj).flat[(int)(c) * PANEL_Q(T, T_VEC, MINQ) + (int)(r)])
|
||||
|
||||
/* API macros */
|
||||
#define BUILD_PANEL(arch, element) build_panel_##arch##_##element
|
||||
#define STORE_PANEL(arch, element) store_panel_##arch##_##element
|
||||
|
||||
#define DECLARE_BUILD_PANEL(arch, element) \
|
||||
INTERNAL void SN_DECL BUILD_PANEL(arch, element)( \
|
||||
MAT_PANEL_##arch(element) *restrict panel, \
|
||||
MAT_KERNEL(element) const *const matrix, int col_length, int row_length, \
|
||||
int col_index, int row_index)
|
||||
#define DECLARE_STORE_PANEL(arch, element) \
|
||||
INTERNAL void SN_DECL STORE_PANEL(arch, element)(MAT_PANEL_##arch(element) \
|
||||
const *const panel, \
|
||||
MAT_KERNEL(element) *restrict matrix, \
|
||||
int col_length, int row_length, \
|
||||
int col_index, int row_index)
|
||||
|
||||
/* Declarations for AVX float variant */
|
||||
DECLARE_BUILD_PANEL(avx, float);
|
||||
DECLARE_BUILD_PANEL(512, float);
|
||||
|
||||
DECLARE_STORE_PANEL(avx, float);
|
||||
DECLARE_STORE_PANEL(512, float);
|
||||
DECLARE_STORE_PANEL(512, float);
|
||||
|
||||
DECLARE_BUILD_PANEL(512, double);
|
||||
|
||||
DECLARE_STORE_PANEL(512, double);
|
||||
|
||||
#endif /* SN_MATKERNEL */
|
||||
|
||||
@@ -1,64 +1,64 @@
|
||||
#ifndef SN_TARGET
|
||||
#define SN_TARGET
|
||||
|
||||
#include "sn_internal.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define SN_OS_WINDOWS 0
|
||||
#define SN_OS_LINUX 1
|
||||
#define SN_OS_MACOS 2
|
||||
#define SN_OS_IOS 3
|
||||
#define SN_OS_ANDROID 4
|
||||
#define SN_OS_UNKNOWN 5
|
||||
|
||||
#define SN_ARCH_X86_64 0
|
||||
#define SN_ARCH_ARM64 1
|
||||
#define SN_ARCH_RISCV64 2
|
||||
#define SN_ARCH_PPC64le 3
|
||||
|
||||
/*
|
||||
* Target selection policy:
|
||||
* - Default (no SN_EXTERN_TARGET): fixed Windows + x86_64.
|
||||
* - External (SN_EXTERN_TARGET): build system must provide SN_OS and SN_ARCH.
|
||||
*/
|
||||
#ifndef SN_EXTERN_TARGET
|
||||
|
||||
#define SN_OS_TARGET SN_OS_WINDOWS
|
||||
#define SN_ARCH_TARGET SN_ARCH_X86_64
|
||||
|
||||
#else
|
||||
|
||||
#ifndef SN_OS_TARGET
|
||||
#error "SN_EXTERN_TARGET is defined but SN_OS is not provided."
|
||||
#endif
|
||||
|
||||
#ifndef SN_ARCH_TARGET
|
||||
#error "SN_EXTERN_TARGET is defined but SN_ARCH is not provided."
|
||||
#endif
|
||||
|
||||
/* Validate externally supplied values are within known enum constants. */
|
||||
#if (SN_OS_TARGET != SN_OS_WINDOWS) && (SN_OS_TARGET != SN_OS_LINUX) && \
|
||||
(SN_OS_TARGET != SN_OS_MACOS) && (SN_OS_TARGET != SN_OS_IOS) && \
|
||||
(SN_OS_TARGET != SN_OS_ANDROID) && (SN_OS_TARGET != SN_OS_UNKNOWN)
|
||||
#error "SN_OS has an invalid value. Use SN_OS_<...> enum constants."
|
||||
#endif
|
||||
|
||||
#if (SN_ARCH_TARGET != SN_ARCH_X86_64) && (SN_ARCH_TARGET != SN_ARCH_ARM64) && \
|
||||
(SN_ARCH_TARGET != SN_ARCH_RISCV64) && (SN_ARCH_TARGET != SN_ARCH_PPC64le)
|
||||
#error "SN_ARCH has an invalid value. Use SN_ARCH_<...> enum constants."
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define SN_IS_OS(os) ((SN_OS_TARGET) == (os))
|
||||
|
||||
#define SN_IS_ARCH(arch) ((SN_ARCH_TARGET) == (arch))
|
||||
|
||||
typedef union SIMDID {
|
||||
uint64_t mask;
|
||||
char make_byte[8];
|
||||
} SIMDID;
|
||||
|
||||
SN_API SIMDID SN_DECL sn_get_simd_level();
|
||||
|
||||
#endif // SN_TARGET
|
||||
#ifndef SN_TARGET
|
||||
#define SN_TARGET
|
||||
|
||||
#include "sn_internal.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define SN_OS_WINDOWS 0
|
||||
#define SN_OS_LINUX 1
|
||||
#define SN_OS_MACOS 2
|
||||
#define SN_OS_IOS 3
|
||||
#define SN_OS_ANDROID 4
|
||||
#define SN_OS_UNKNOWN 5
|
||||
|
||||
#define SN_ARCH_X86_64 0
|
||||
#define SN_ARCH_ARM64 1
|
||||
#define SN_ARCH_RISCV64 2
|
||||
#define SN_ARCH_PPC64le 3
|
||||
|
||||
/*
|
||||
* Target selection policy:
|
||||
* - Default (no SN_EXTERN_TARGET): fixed Windows + x86_64.
|
||||
* - External (SN_EXTERN_TARGET): build system must provide SN_OS and SN_ARCH.
|
||||
*/
|
||||
#ifndef SN_EXTERN_TARGET
|
||||
|
||||
#define SN_OS_TARGET SN_OS_WINDOWS
|
||||
#define SN_ARCH_TARGET SN_ARCH_X86_64
|
||||
|
||||
#else
|
||||
|
||||
#ifndef SN_OS_TARGET
|
||||
#error "SN_EXTERN_TARGET is defined but SN_OS is not provided."
|
||||
#endif
|
||||
|
||||
#ifndef SN_ARCH_TARGET
|
||||
#error "SN_EXTERN_TARGET is defined but SN_ARCH is not provided."
|
||||
#endif
|
||||
|
||||
/* Validate externally supplied values are within known enum constants. */
|
||||
#if (SN_OS_TARGET != SN_OS_WINDOWS) && (SN_OS_TARGET != SN_OS_LINUX) && \
|
||||
(SN_OS_TARGET != SN_OS_MACOS) && (SN_OS_TARGET != SN_OS_IOS) && \
|
||||
(SN_OS_TARGET != SN_OS_ANDROID) && (SN_OS_TARGET != SN_OS_UNKNOWN)
|
||||
#error "SN_OS has an invalid value. Use SN_OS_<...> enum constants."
|
||||
#endif
|
||||
|
||||
#if (SN_ARCH_TARGET != SN_ARCH_X86_64) && (SN_ARCH_TARGET != SN_ARCH_ARM64) && \
|
||||
(SN_ARCH_TARGET != SN_ARCH_RISCV64) && (SN_ARCH_TARGET != SN_ARCH_PPC64le)
|
||||
#error "SN_ARCH has an invalid value. Use SN_ARCH_<...> enum constants."
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define SN_IS_OS(os) ((SN_OS_TARGET) == (os))
|
||||
|
||||
#define SN_IS_ARCH(arch) ((SN_ARCH_TARGET) == (arch))
|
||||
|
||||
typedef union SIMDID {
|
||||
uint64_t mask;
|
||||
char make_byte[8];
|
||||
} SIMDID;
|
||||
|
||||
SN_API SIMDID SN_DECL sn_get_simd_level();
|
||||
|
||||
#endif // SN_TARGET
|
||||
|
||||
+1076
-1076
File diff suppressed because it is too large
Load Diff
@@ -1,75 +1,75 @@
|
||||
#include "StgSharpC.h"
|
||||
#include "gl.h"
|
||||
#include "glfw3.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
extern GladGLContext *currentContext;
|
||||
extern char infolog[512];
|
||||
|
||||
SSCAPI int SSCDECL glCheckShaderStat(GladGLContext *context, uint64_t shaderHandle, int key,
|
||||
char **logRef)
|
||||
{
|
||||
int stat = 0;
|
||||
context->GetShaderiv(shaderHandle, key, &stat);
|
||||
if (!stat) {
|
||||
context->GetShaderInfoLog(shaderHandle, 512, NULL, infolog);
|
||||
}
|
||||
*logRef = infolog;
|
||||
return stat;
|
||||
}
|
||||
|
||||
SSCAPI void SSCDECL initGL(int majorVersion, int minorVersion)
|
||||
{
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, majorVersion);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, minorVersion);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||
}
|
||||
|
||||
SSCAPI GLFWglproc SSCDECL loadGlfuncDefault(char const *procName)
|
||||
{
|
||||
void *ret = glfwGetProcAddress(procName);
|
||||
// printf("%llu\n", (uint64_t)ret);
|
||||
if (ret == NULL) {
|
||||
strcpy_s(infolog,30, "Failed to load OpenGL api:");
|
||||
for (size_t i = 0; i < sizeof(procName); i++) {
|
||||
infolog[30 + i] = procName[i];
|
||||
}
|
||||
//printf("%s\n", infolog);
|
||||
}
|
||||
return (GLFWglproc)ret;
|
||||
}
|
||||
|
||||
SSCAPI unsigned int linkShaderProgram(GladGLContext *context, GLuint shaderProgram)
|
||||
{
|
||||
context->LinkProgram(shaderProgram);
|
||||
|
||||
int success;
|
||||
context->GetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
context->GetProgramInfoLog(shaderProgram, 512, NULL, infolog);
|
||||
return 0;
|
||||
} else {
|
||||
return shaderProgram;
|
||||
}
|
||||
}
|
||||
|
||||
SSCAPI void SSCDECL loadImageData(char const *location, Image *out, imageLoader loader)
|
||||
{
|
||||
if (loader == NULL) {
|
||||
loader = stbi_load;
|
||||
}
|
||||
out->pixelPtr = loader(location, &(out->width), &(out->height), &(out->channel), 0);
|
||||
}
|
||||
|
||||
SSCAPI void SSCDECL unloadImageData(Image *restrict out)
|
||||
{
|
||||
free(out->pixelPtr);
|
||||
}
|
||||
|
||||
SSCAPI char *SSCDECL readLog()
|
||||
{
|
||||
infolog[511] = '\0';
|
||||
return infolog;
|
||||
}
|
||||
#include "StgSharpC.h"
|
||||
#include "gl.h"
|
||||
#include "glfw3.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
extern GladGLContext *currentContext;
|
||||
extern char infolog[512];
|
||||
|
||||
SSCAPI int SSCDECL glCheckShaderStat(GladGLContext *context, uint64_t shaderHandle, int key,
|
||||
char **logRef)
|
||||
{
|
||||
int stat = 0;
|
||||
context->GetShaderiv(shaderHandle, key, &stat);
|
||||
if (!stat) {
|
||||
context->GetShaderInfoLog(shaderHandle, 512, NULL, infolog);
|
||||
}
|
||||
*logRef = infolog;
|
||||
return stat;
|
||||
}
|
||||
|
||||
SSCAPI void SSCDECL initGL(int majorVersion, int minorVersion)
|
||||
{
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, majorVersion);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, minorVersion);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||
}
|
||||
|
||||
SSCAPI GLFWglproc SSCDECL loadGlfuncDefault(char const *procName)
|
||||
{
|
||||
void *ret = glfwGetProcAddress(procName);
|
||||
// printf("%llu\n", (uint64_t)ret);
|
||||
if (ret == NULL) {
|
||||
strcpy_s(infolog,30, "Failed to load OpenGL api:");
|
||||
for (size_t i = 0; i < sizeof(procName); i++) {
|
||||
infolog[30 + i] = procName[i];
|
||||
}
|
||||
//printf("%s\n", infolog);
|
||||
}
|
||||
return (GLFWglproc)ret;
|
||||
}
|
||||
|
||||
SSCAPI unsigned int linkShaderProgram(GladGLContext *context, GLuint shaderProgram)
|
||||
{
|
||||
context->LinkProgram(shaderProgram);
|
||||
|
||||
int success;
|
||||
context->GetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
context->GetProgramInfoLog(shaderProgram, 512, NULL, infolog);
|
||||
return 0;
|
||||
} else {
|
||||
return shaderProgram;
|
||||
}
|
||||
}
|
||||
|
||||
SSCAPI void SSCDECL loadImageData(char const *location, Image *out, imageLoader loader)
|
||||
{
|
||||
if (loader == NULL) {
|
||||
loader = stbi_load;
|
||||
}
|
||||
out->pixelPtr = loader(location, &(out->width), &(out->height), &(out->channel), 0);
|
||||
}
|
||||
|
||||
SSCAPI void SSCDECL unloadImageData(Image *restrict out)
|
||||
{
|
||||
free(out->pixelPtr);
|
||||
}
|
||||
|
||||
SSCAPI char *SSCDECL readLog()
|
||||
{
|
||||
infolog[511] = '\0';
|
||||
return infolog;
|
||||
}
|
||||
|
||||
+214
-214
@@ -1,214 +1,214 @@
|
||||
#include "sn_target.h"
|
||||
#include "sn_intrinsic.h"
|
||||
|
||||
static SIMDID global_simdid = { 0 };
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrincontext.x86.h"
|
||||
|
||||
#include <immintrin.h>
|
||||
#include <string.h>
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#else
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
static void get_cpuid(int leaf, int subleaf, int *eax, int *ebx, int *ecx, int *edx)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
int regs[4];
|
||||
__cpuidex(regs, leaf, subleaf);
|
||||
*eax = regs[0];
|
||||
*ebx = regs[1];
|
||||
*ecx = regs[2];
|
||||
*edx = regs[3];
|
||||
#else
|
||||
unsigned int a, b, c, d;
|
||||
__cpuid_count((unsigned int)leaf, (unsigned int)subleaf, a, b, c, d);
|
||||
*eax = (int)a;
|
||||
*ebx = (int)b;
|
||||
*ecx = (int)c;
|
||||
*edx = (int)d;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int xgetbv_has_xmm_ymm(void)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
unsigned __int64 xcr0 = _xgetbv(0);
|
||||
#else
|
||||
unsigned long long xcr0 = __builtin_ia32_xgetbv(0);
|
||||
#endif
|
||||
return ((xcr0 & 0x6) == 0x6);
|
||||
}
|
||||
|
||||
static int xgetbv_has_avx512_state(void)
|
||||
{
|
||||
const unsigned long long mask = (1ull << 0) | (1ull << 1) | (1ull << 2) | (1ull << 5) |
|
||||
(1ull << 6);
|
||||
#if defined(_MSC_VER)
|
||||
unsigned __int64 xcr0 = _xgetbv(0);
|
||||
#else
|
||||
unsigned long long xcr0 = __builtin_ia32_xgetbv(0);
|
||||
#endif
|
||||
return ((xcr0 & mask) == mask);
|
||||
}
|
||||
|
||||
static int is_intel_dual_avx512(int family, int model)
|
||||
{
|
||||
return (family == 6) && (model == 0x55); /* SKX/CLX/CPX */
|
||||
}
|
||||
|
||||
static int is_intel_native_avx512(int family, int model)
|
||||
{
|
||||
if (family != 6)
|
||||
return 0;
|
||||
switch (model) {
|
||||
case 0x6A: /* ICX */
|
||||
case 0x6C: /* ICX stepping */
|
||||
case 0x8F: /* SPR/EMR */
|
||||
case 0xCF: /* GNR */
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
SN_API SIMDID SN_DECL sn_get_simd_level()
|
||||
{
|
||||
if (global_simdid.mask) {
|
||||
return global_simdid;
|
||||
}
|
||||
|
||||
int eax = 0, ebx = 0, ecx = 0, edx = 0;
|
||||
|
||||
/* Vendor */
|
||||
get_cpuid(0, 0, &eax, &ebx, &ecx, &edx);
|
||||
char vendor[13];
|
||||
((int *)vendor)[0] = ebx;
|
||||
((int *)vendor)[1] = edx;
|
||||
((int *)vendor)[2] = ecx;
|
||||
vendor[12] = '\0';
|
||||
const int is_intel = (strcmp(vendor, "GenuineIntel") == 0);
|
||||
const int is_amd = (strcmp(vendor, "AuthenticAMD") == 0) ||
|
||||
(strcmp(vendor, "HygonGenuine") == 0);
|
||||
|
||||
/* CPUID.1 */
|
||||
get_cpuid(1, 0, &eax, &ebx, &ecx, &edx);
|
||||
int family = ((eax >> 8) & 0xF) + ((eax >> 20) & 0xFF0);
|
||||
int model = ((eax >> 4) & 0xF) | ((eax >> 12) & 0xF0);
|
||||
|
||||
int has_sse42 = (ecx & (1 << 20)) != 0;
|
||||
int has_avx = (ecx & (1 << 28)) != 0;
|
||||
int has_osxsave = (ecx & (1 << 27)) != 0;
|
||||
int has_fma = (ecx & (1 << 12)) != 0;
|
||||
int has_f16c = (ecx & (1 << 29)) != 0;
|
||||
|
||||
uint64_t root = SIMDID_PACK_ROOT(SIMDID_ROOT_X86_64);
|
||||
uint64_t manu = SIMDID_PACK_MANU(is_intel ? SIMDID_MANU_INTEL :
|
||||
is_amd ? SIMDID_MANU_AMD :
|
||||
SIMDID_MANU_UNKNOWN);
|
||||
uint64_t main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_NONE);
|
||||
uint64_t avx512_bits = 0;
|
||||
uint64_t amx_bits = 0;
|
||||
uint64_t avx_bits = 0;
|
||||
|
||||
/* Baseline main level */
|
||||
if (has_sse42)
|
||||
main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_SSE);
|
||||
|
||||
if (has_avx && has_osxsave && xgetbv_has_xmm_ymm()) {
|
||||
avx_bits |= SIMDID_AVX;
|
||||
|
||||
/* CPUID.7.0 */
|
||||
get_cpuid(7, 0, &eax, &ebx, &ecx, &edx);
|
||||
const int has_bmi1 = (ebx & (1 << 3)) != 0;
|
||||
const int has_bmi2 = (ebx & (1 << 8)) != 0;
|
||||
const int has_avx2 = (ebx & (1 << 5)) != 0;
|
||||
const int has_avx512f = (ebx & (1 << 16)) != 0;
|
||||
const int has_avx512dq = (ebx & (1 << 17)) != 0;
|
||||
const int has_avx512bw = (ebx & (1 << 30)) != 0;
|
||||
const int has_avx512vl = (ebx & (1u << 31)) != 0;
|
||||
const int has_avx512_vnni = (ebx & (1 << 11)) != 0;
|
||||
const int has_vbmi = (ecx & (1 << 1)) != 0;
|
||||
const int has_vbmi2 = (ecx & (1 << 6)) != 0;
|
||||
|
||||
/* leaf 7, subleaf 1 for BF16/FP16 */
|
||||
get_cpuid(7, 1, &eax, &ebx, &ecx, &edx);
|
||||
const int has_bf16 = (eax & (1 << 5)) != 0; /* AVX512_BF16 */
|
||||
const int has_fp16 = (eax & (1 << 23)) != 0; /* AVX512_FP16 */
|
||||
|
||||
/* AMX in leaf 7 subleaf 0 EDX bits 24/25/26 */
|
||||
const int has_amx_tile = (edx & (1 << 24)) != 0;
|
||||
const int has_amx_int8 = (edx & (1 << 25)) != 0;
|
||||
const int has_amx_bf16 = (edx & (1 << 26)) != 0;
|
||||
|
||||
if (has_avx2) {
|
||||
avx_bits |= SIMDID_AVX2;
|
||||
if (has_fma)
|
||||
avx_bits |= SIMDID_AVX_FMA;
|
||||
if (has_f16c)
|
||||
avx_bits |= SIMDID_AVX_F16C;
|
||||
|
||||
main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AVX2);
|
||||
}
|
||||
|
||||
if (has_avx512f && xgetbv_has_avx512_state()) {
|
||||
/* Ensure base subset present */
|
||||
if (has_avx512bw && has_avx512vl && has_avx512dq) {
|
||||
avx512_bits |= SIMDID_AVX512_BASE;
|
||||
}
|
||||
if (has_avx512_vnni)
|
||||
avx512_bits |= SIMDID_AVX512_VNNI;
|
||||
if (has_bf16)
|
||||
avx512_bits |= SIMDID_AVX512_BF16;
|
||||
if (has_fp16)
|
||||
avx512_bits |= SIMDID_AVX512_FP16;
|
||||
if (has_vbmi)
|
||||
avx512_bits |= SIMDID_AVX512_VBMI;
|
||||
if (has_vbmi2)
|
||||
avx512_bits |= SIMDID_AVX512_VBMI2;
|
||||
|
||||
/* impl classification */
|
||||
const int glue = is_amd || is_intel_dual_avx512(family, model);
|
||||
const int native512 = is_intel_native_avx512(family, model);
|
||||
if (glue) {
|
||||
avx512_bits |= SIMDID_AVX512_IMPL_DUAL;
|
||||
} else if (native512) {
|
||||
avx512_bits |= SIMDID_AVX512_IMPL_NATIVE;
|
||||
} else {
|
||||
avx512_bits |= SIMDID_AVX512_IMPL_UNKNOWN;
|
||||
}
|
||||
|
||||
/* main level for AVX512 */
|
||||
main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AVX512);
|
||||
|
||||
/* AMX promotion if present */
|
||||
if (has_amx_tile) {
|
||||
amx_bits |= SIMDID_AMX_TILE;
|
||||
if (has_amx_int8)
|
||||
amx_bits |= SIMDID_AMX_INT8;
|
||||
if (has_amx_bf16)
|
||||
amx_bits |= SIMDID_AMX_BF16;
|
||||
main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AMX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
global_simdid.mask = root | manu | main_lvl | SIMDID_PACK_AVX512(avx512_bits) |
|
||||
SIMDID_PACK_AMX(amx_bits) | SIMDID_PACK_AVX(avx_bits);
|
||||
return global_simdid;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
SIMDID sn_get_simd_level()
|
||||
{
|
||||
SIMDID simd_id;
|
||||
simd_id.mask = 0;
|
||||
return simd_id; /* non-x86: no SIMD level probing */
|
||||
}
|
||||
|
||||
#endif
|
||||
#include "sn_target.h"
|
||||
#include "sn_intrinsic.h"
|
||||
|
||||
static SIMDID global_simdid = { 0 };
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrincontext.x86.h"
|
||||
|
||||
#include <immintrin.h>
|
||||
#include <string.h>
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#else
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
static void get_cpuid(int leaf, int subleaf, int *eax, int *ebx, int *ecx, int *edx)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
int regs[4];
|
||||
__cpuidex(regs, leaf, subleaf);
|
||||
*eax = regs[0];
|
||||
*ebx = regs[1];
|
||||
*ecx = regs[2];
|
||||
*edx = regs[3];
|
||||
#else
|
||||
unsigned int a, b, c, d;
|
||||
__cpuid_count((unsigned int)leaf, (unsigned int)subleaf, a, b, c, d);
|
||||
*eax = (int)a;
|
||||
*ebx = (int)b;
|
||||
*ecx = (int)c;
|
||||
*edx = (int)d;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int xgetbv_has_xmm_ymm(void)
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
unsigned __int64 xcr0 = _xgetbv(0);
|
||||
#else
|
||||
unsigned long long xcr0 = __builtin_ia32_xgetbv(0);
|
||||
#endif
|
||||
return ((xcr0 & 0x6) == 0x6);
|
||||
}
|
||||
|
||||
static int xgetbv_has_avx512_state(void)
|
||||
{
|
||||
const unsigned long long mask = (1ull << 0) | (1ull << 1) | (1ull << 2) | (1ull << 5) |
|
||||
(1ull << 6);
|
||||
#if defined(_MSC_VER)
|
||||
unsigned __int64 xcr0 = _xgetbv(0);
|
||||
#else
|
||||
unsigned long long xcr0 = __builtin_ia32_xgetbv(0);
|
||||
#endif
|
||||
return ((xcr0 & mask) == mask);
|
||||
}
|
||||
|
||||
static int is_intel_dual_avx512(int family, int model)
|
||||
{
|
||||
return (family == 6) && (model == 0x55); /* SKX/CLX/CPX */
|
||||
}
|
||||
|
||||
static int is_intel_native_avx512(int family, int model)
|
||||
{
|
||||
if (family != 6)
|
||||
return 0;
|
||||
switch (model) {
|
||||
case 0x6A: /* ICX */
|
||||
case 0x6C: /* ICX stepping */
|
||||
case 0x8F: /* SPR/EMR */
|
||||
case 0xCF: /* GNR */
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
SN_API SIMDID SN_DECL sn_get_simd_level()
|
||||
{
|
||||
if (global_simdid.mask) {
|
||||
return global_simdid;
|
||||
}
|
||||
|
||||
int eax = 0, ebx = 0, ecx = 0, edx = 0;
|
||||
|
||||
/* Vendor */
|
||||
get_cpuid(0, 0, &eax, &ebx, &ecx, &edx);
|
||||
char vendor[13];
|
||||
((int *)vendor)[0] = ebx;
|
||||
((int *)vendor)[1] = edx;
|
||||
((int *)vendor)[2] = ecx;
|
||||
vendor[12] = '\0';
|
||||
const int is_intel = (strcmp(vendor, "GenuineIntel") == 0);
|
||||
const int is_amd = (strcmp(vendor, "AuthenticAMD") == 0) ||
|
||||
(strcmp(vendor, "HygonGenuine") == 0);
|
||||
|
||||
/* CPUID.1 */
|
||||
get_cpuid(1, 0, &eax, &ebx, &ecx, &edx);
|
||||
int family = ((eax >> 8) & 0xF) + ((eax >> 20) & 0xFF0);
|
||||
int model = ((eax >> 4) & 0xF) | ((eax >> 12) & 0xF0);
|
||||
|
||||
int has_sse42 = (ecx & (1 << 20)) != 0;
|
||||
int has_avx = (ecx & (1 << 28)) != 0;
|
||||
int has_osxsave = (ecx & (1 << 27)) != 0;
|
||||
int has_fma = (ecx & (1 << 12)) != 0;
|
||||
int has_f16c = (ecx & (1 << 29)) != 0;
|
||||
|
||||
uint64_t root = SIMDID_PACK_ROOT(SIMDID_ROOT_X86_64);
|
||||
uint64_t manu = SIMDID_PACK_MANU(is_intel ? SIMDID_MANU_INTEL :
|
||||
is_amd ? SIMDID_MANU_AMD :
|
||||
SIMDID_MANU_UNKNOWN);
|
||||
uint64_t main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_NONE);
|
||||
uint64_t avx512_bits = 0;
|
||||
uint64_t amx_bits = 0;
|
||||
uint64_t avx_bits = 0;
|
||||
|
||||
/* Baseline main level */
|
||||
if (has_sse42)
|
||||
main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_SSE);
|
||||
|
||||
if (has_avx && has_osxsave && xgetbv_has_xmm_ymm()) {
|
||||
avx_bits |= SIMDID_AVX;
|
||||
|
||||
/* CPUID.7.0 */
|
||||
get_cpuid(7, 0, &eax, &ebx, &ecx, &edx);
|
||||
const int has_bmi1 = (ebx & (1 << 3)) != 0;
|
||||
const int has_bmi2 = (ebx & (1 << 8)) != 0;
|
||||
const int has_avx2 = (ebx & (1 << 5)) != 0;
|
||||
const int has_avx512f = (ebx & (1 << 16)) != 0;
|
||||
const int has_avx512dq = (ebx & (1 << 17)) != 0;
|
||||
const int has_avx512bw = (ebx & (1 << 30)) != 0;
|
||||
const int has_avx512vl = (ebx & (1u << 31)) != 0;
|
||||
const int has_avx512_vnni = (ebx & (1 << 11)) != 0;
|
||||
const int has_vbmi = (ecx & (1 << 1)) != 0;
|
||||
const int has_vbmi2 = (ecx & (1 << 6)) != 0;
|
||||
|
||||
/* leaf 7, subleaf 1 for BF16/FP16 */
|
||||
get_cpuid(7, 1, &eax, &ebx, &ecx, &edx);
|
||||
const int has_bf16 = (eax & (1 << 5)) != 0; /* AVX512_BF16 */
|
||||
const int has_fp16 = (eax & (1 << 23)) != 0; /* AVX512_FP16 */
|
||||
|
||||
/* AMX in leaf 7 subleaf 0 EDX bits 24/25/26 */
|
||||
const int has_amx_tile = (edx & (1 << 24)) != 0;
|
||||
const int has_amx_int8 = (edx & (1 << 25)) != 0;
|
||||
const int has_amx_bf16 = (edx & (1 << 26)) != 0;
|
||||
|
||||
if (has_avx2) {
|
||||
avx_bits |= SIMDID_AVX2;
|
||||
if (has_fma)
|
||||
avx_bits |= SIMDID_AVX_FMA;
|
||||
if (has_f16c)
|
||||
avx_bits |= SIMDID_AVX_F16C;
|
||||
|
||||
main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AVX2);
|
||||
}
|
||||
|
||||
if (has_avx512f && xgetbv_has_avx512_state()) {
|
||||
/* Ensure base subset present */
|
||||
if (has_avx512bw && has_avx512vl && has_avx512dq) {
|
||||
avx512_bits |= SIMDID_AVX512_BASE;
|
||||
}
|
||||
if (has_avx512_vnni)
|
||||
avx512_bits |= SIMDID_AVX512_VNNI;
|
||||
if (has_bf16)
|
||||
avx512_bits |= SIMDID_AVX512_BF16;
|
||||
if (has_fp16)
|
||||
avx512_bits |= SIMDID_AVX512_FP16;
|
||||
if (has_vbmi)
|
||||
avx512_bits |= SIMDID_AVX512_VBMI;
|
||||
if (has_vbmi2)
|
||||
avx512_bits |= SIMDID_AVX512_VBMI2;
|
||||
|
||||
/* impl classification */
|
||||
const int glue = is_amd || is_intel_dual_avx512(family, model);
|
||||
const int native512 = is_intel_native_avx512(family, model);
|
||||
if (glue) {
|
||||
avx512_bits |= SIMDID_AVX512_IMPL_DUAL;
|
||||
} else if (native512) {
|
||||
avx512_bits |= SIMDID_AVX512_IMPL_NATIVE;
|
||||
} else {
|
||||
avx512_bits |= SIMDID_AVX512_IMPL_UNKNOWN;
|
||||
}
|
||||
|
||||
/* main level for AVX512 */
|
||||
main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AVX512);
|
||||
|
||||
/* AMX promotion if present */
|
||||
if (has_amx_tile) {
|
||||
amx_bits |= SIMDID_AMX_TILE;
|
||||
if (has_amx_int8)
|
||||
amx_bits |= SIMDID_AMX_INT8;
|
||||
if (has_amx_bf16)
|
||||
amx_bits |= SIMDID_AMX_BF16;
|
||||
main_lvl = SIMDID_PACK_MAIN(SIMDID_MAIN_LVL_AMX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
global_simdid.mask = root | manu | main_lvl | SIMDID_PACK_AVX512(avx512_bits) |
|
||||
SIMDID_PACK_AMX(amx_bits) | SIMDID_PACK_AVX(avx_bits);
|
||||
return global_simdid;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
SIMDID sn_get_simd_level()
|
||||
{
|
||||
SIMDID simd_id;
|
||||
simd_id.mask = 0;
|
||||
return simd_id; /* non-x86: no SIMD level probing */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
#include "StgSharpNative.h"
|
||||
#include "sn_matkernel.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* Define and initialize a global zero kernel aligned to 64 bytes for universal ISA usage */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
__declspec(align(64)) sn_zero_kernel_u64 SN_ZERO_KERNEL;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
static void init_zero_kernel(void)
|
||||
{
|
||||
for (int c = 0; c < 4; ++c) {
|
||||
for (int r = 0; r < 4; ++r) {
|
||||
SN_ZERO_KERNEL.m[r][c] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
switch (ul_reason_for_call) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
init_zero_kernel();
|
||||
return 1;
|
||||
case DLL_THREAD_ATTACH:
|
||||
return 1;
|
||||
case DLL_THREAD_DETACH:
|
||||
return 1;
|
||||
case DLL_PROCESS_DETACH:
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
attribute((constructor)) void DllMain()
|
||||
{
|
||||
init_zero_kernel();
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
#include "StgSharpNative.h"
|
||||
#include "sn_matkernel.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* Define and initialize a global zero kernel aligned to 64 bytes for universal ISA usage */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
__declspec(align(64)) sn_zero_kernel_u64 SN_ZERO_KERNEL;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
static void init_zero_kernel(void)
|
||||
{
|
||||
for (int c = 0; c < 4; ++c) {
|
||||
for (int r = 0; r < 4; ++r) {
|
||||
SN_ZERO_KERNEL.m[r][c] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
switch (ul_reason_for_call) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
init_zero_kernel();
|
||||
return 1;
|
||||
case DLL_THREAD_ATTACH:
|
||||
return 1;
|
||||
case DLL_THREAD_DETACH:
|
||||
return 1;
|
||||
case DLL_PROCESS_DETACH:
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
attribute((constructor)) void DllMain()
|
||||
{
|
||||
init_zero_kernel();
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
+123
-123
@@ -1,123 +1,123 @@
|
||||
#include "StgSharpNative.h"
|
||||
#include "glfw_function.h"
|
||||
#include <string.h>
|
||||
|
||||
SN_API void SN_DECL load_glfw_functions(GLFWFunctionTable *table)
|
||||
{
|
||||
table->glfwCreateCursor = glfwCreateCursor;
|
||||
table->glfwCreateStandardCursor = glfwCreateStandardCursor;
|
||||
table->glfwCreateWindow = glfwCreateWindow;
|
||||
table->glfwDefaultWindowHints = glfwDefaultWindowHints;
|
||||
table->glfwDestroyCursor = glfwDestroyCursor;
|
||||
table->glfwDestroyWindow = glfwDestroyWindow;
|
||||
table->glfwExtensionSupported = glfwExtensionSupported;
|
||||
table->glfwFocusWindow = glfwFocusWindow;
|
||||
table->glfwGetClipboardString = glfwGetClipboardString;
|
||||
table->glfwGetCurrentContext = glfwGetCurrentContext;
|
||||
table->glfwGetCursorPos = glfwGetCursorPos;
|
||||
table->glfwGetError = glfwGetError;
|
||||
table->glfwGetFrameBufferSize = glfwGetFramebufferSize;
|
||||
table->glfwGetGamepadName = glfwGetGamepadName;
|
||||
table->glfwGetGamepadState = glfwGetGamepadState;
|
||||
table->glfwGetGammaRamp = glfwGetGammaRamp;
|
||||
table->glfwGetInputMode = glfwGetInputMode;
|
||||
table->glfwGetJoystickAxes = glfwGetJoystickAxes;
|
||||
table->glfwGetJoystickButtons = glfwGetJoystickButtons;
|
||||
table->glfwGetJoystickGUID = glfwGetJoystickGUID;
|
||||
table->glfwGetJoystickHats = glfwGetJoystickHats;
|
||||
table->glfwGetJoystickName = glfwGetJoystickName;
|
||||
table->glfwGetJoystickUserPointer = glfwGetJoystickUserPointer;
|
||||
table->glfwGetKey = glfwGetKey;
|
||||
table->glfwGetKeyName = glfwGetKeyName;
|
||||
table->glfwGetKeyScancode = glfwGetKeyScancode;
|
||||
table->glfwGetMonitorContentScale = glfwGetMonitorContentScale;
|
||||
table->glfwGetMonitorName = glfwGetMonitorName;
|
||||
table->glfwGetMonitorPhysicalSize = glfwGetMonitorPhysicalSize;
|
||||
table->glfwGetMonitorPos = glfwGetMonitorPos;
|
||||
table->glfwGetMonitors = glfwGetMonitors;
|
||||
table->glfwGetMonitorUserPointer = glfwGetMonitorUserPointer;
|
||||
table->glfwGetMonitorWorkarea = glfwGetMonitorWorkarea;
|
||||
table->glfwGetMouseButton = glfwGetMouseButton;
|
||||
table->glfwGetPrimaryMonitor = glfwGetPrimaryMonitor;
|
||||
table->glfwGetProcAddress = glfwGetProcAddress;
|
||||
table->glfwGetRequiredInstanceExtensions = glfwGetRequiredInstanceExtensions;
|
||||
table->glfwGetTime = glfwGetTime;
|
||||
table->glfwGetTimerFrequency = glfwGetTimerFrequency;
|
||||
table->glfwGetTimerValue = glfwGetTimerValue;
|
||||
table->glfwGetVersion = glfwGetVersion;
|
||||
table->glfwGetVersionString = glfwGetVersionString;
|
||||
table->glfwGetVideoMode = glfwGetVideoMode;
|
||||
table->glfwGetVideoModes = glfwGetVideoModes;
|
||||
table->glfwGetWindowAttrib = glfwGetWindowAttrib;
|
||||
table->glfwGetWindowContentScale = glfwGetWindowContentScale;
|
||||
table->glfwGetWindowFrameSize = glfwGetWindowFrameSize;
|
||||
table->glfwGetWindowMonitor = glfwGetWindowMonitor;
|
||||
table->glfwGetWindowOpacity = glfwGetWindowOpacity;
|
||||
table->glfwGetWindowPos = glfwGetWindowPos;
|
||||
table->glfwGetWindowSize = glfwGetWindowSize;
|
||||
table->glfwGetWindowUserPointer = glfwGetWindowUserPointer;
|
||||
table->glfwHideWindow = glfwHideWindow;
|
||||
table->glfwIconifyWindow = glfwIconifyWindow;
|
||||
table->glfwInit = glfwInit;
|
||||
table->glfwInitHint = glfwInitHint;
|
||||
table->glfwJoystickIsGamePad = glfwJoystickIsGamepad;
|
||||
table->glfwJoystickPresent = glfwJoystickPresent;
|
||||
table->glfwMakeContextCurrent = glfwMakeContextCurrent;
|
||||
table->glfwMaximizeWindow = glfwMaximizeWindow;
|
||||
table->glfwPollEvents = glfwPollEvents;
|
||||
table->glfwPostEmptyEvent = glfwPostEmptyEvent;
|
||||
table->glfwRawMouseMotionSupported = glfwRawMouseMotionSupported;
|
||||
table->glfwRequestWindowAttention = glfwRequestWindowAttention;
|
||||
table->glfwRestoreWindow = glfwRestoreWindow;
|
||||
table->glfwSetCharCallback = glfwSetCharCallback;
|
||||
table->glfwSetCharModsCallback = glfwSetCharModsCallback;
|
||||
table->glfwSetClipboardString = glfwSetClipboardString;
|
||||
table->glfwSetCursor = glfwSetCursor;
|
||||
table->glfwSetCursorEnterCallback = glfwSetCursorEnterCallback;
|
||||
table->glfwSetCursorPos = glfwSetCursorPos;
|
||||
table->glfwSetCursorPosCallback = glfwSetCursorPosCallback;
|
||||
table->glfwSetDropCallback = glfwSetDropCallback;
|
||||
table->glfwSetErrorCallback = glfwSetErrorCallback;
|
||||
table->glfwSetFramebufferSizeCallback = glfwSetFramebufferSizeCallback;
|
||||
table->glfwSetGamma = glfwSetGamma;
|
||||
table->glfwSetGammaRamp = glfwSetGammaRamp;
|
||||
table->glfwSetInputMode = glfwSetInputMode;
|
||||
table->glfwSetJoystickCallback = glfwSetJoystickCallback;
|
||||
table->glfwSetJoystickUserPointer = glfwSetJoystickUserPointer;
|
||||
table->glfwSetKeyCallback = glfwSetKeyCallback;
|
||||
table->glfwSetMonitorCallback = glfwSetMonitorCallback;
|
||||
table->glfwSetMonitorUserPointer = glfwSetMonitorUserPointer;
|
||||
table->glfwSetMouseButtonCallback = glfwSetMouseButtonCallback;
|
||||
table->glfwSetScrollCallback = glfwSetScrollCallback;
|
||||
table->glfwSetTime = glfwSetTime;
|
||||
table->glfwSetWindowAspectRatio = glfwSetWindowAspectRatio;
|
||||
table->glfwSetWindowAttrib = glfwSetWindowAttrib;
|
||||
table->glfwSetWindowCloseCallback = glfwSetWindowCloseCallback;
|
||||
table->glfwSetWindowContentScaleCallback = glfwSetWindowContentScaleCallback;
|
||||
table->glfwSetWindowFocusCallback = glfwSetWindowFocusCallback;
|
||||
table->glfwSetWindowIcon = glfwSetWindowIcon;
|
||||
table->glfwSetWindowIconifyCallback = glfwSetWindowIconifyCallback;
|
||||
table->glfwSetWindowMaximizeCallback = glfwSetWindowMaximizeCallback;
|
||||
table->glfwSetWindowMonitor = glfwSetWindowMonitor;
|
||||
table->glfwSetWindowOpacity = glfwSetWindowOpacity;
|
||||
table->glfwSetWindowPos = glfwSetWindowPos;
|
||||
table->glfwSetWindowPosCallback = glfwSetWindowPosCallback;
|
||||
table->glfwSetWindowRefreshCallback = glfwSetWindowRefreshCallback;
|
||||
table->glfwSetWindowShouldClose = glfwSetWindowShouldClose;
|
||||
table->glfwSetWindowSize = glfwSetWindowSize;
|
||||
table->glfwSetWindowSizeCallback = glfwSetWindowSizeCallback;
|
||||
table->glfwSetWindowSizeLimits = glfwSetWindowSizeLimits;
|
||||
table->glfwSetWindowTitle = glfwSetWindowTitle;
|
||||
table->glfwSetWindowUserPointer = glfwSetWindowUserPointer;
|
||||
table->glfwShowWindow = glfwShowWindow;
|
||||
table->glfwSwapBuffers = glfwSwapBuffers;
|
||||
table->glfwSwapInterval = glfwSwapInterval;
|
||||
table->glfwTerminate = glfwTerminate;
|
||||
table->glfwUpdateGamePadMappings = glfwUpdateGamepadMappings;
|
||||
table->glfwVulkanSupported = glfwVulkanSupported;
|
||||
table->glfwWaitEvents = glfwWaitEvents;
|
||||
table->glfwWaitEventsTimeout = glfwWaitEventsTimeout;
|
||||
table->glfwWindowHint = glfwWindowHint;
|
||||
table->glfwWindowHintString = glfwWindowHintString;
|
||||
table->glfwWindowShouldClose = glfwWindowShouldClose;
|
||||
}
|
||||
#include "StgSharpNative.h"
|
||||
#include "glfw_function.h"
|
||||
#include <string.h>
|
||||
|
||||
SN_API void SN_DECL load_glfw_functions(GLFWFunctionTable *table)
|
||||
{
|
||||
table->glfwCreateCursor = glfwCreateCursor;
|
||||
table->glfwCreateStandardCursor = glfwCreateStandardCursor;
|
||||
table->glfwCreateWindow = glfwCreateWindow;
|
||||
table->glfwDefaultWindowHints = glfwDefaultWindowHints;
|
||||
table->glfwDestroyCursor = glfwDestroyCursor;
|
||||
table->glfwDestroyWindow = glfwDestroyWindow;
|
||||
table->glfwExtensionSupported = glfwExtensionSupported;
|
||||
table->glfwFocusWindow = glfwFocusWindow;
|
||||
table->glfwGetClipboardString = glfwGetClipboardString;
|
||||
table->glfwGetCurrentContext = glfwGetCurrentContext;
|
||||
table->glfwGetCursorPos = glfwGetCursorPos;
|
||||
table->glfwGetError = glfwGetError;
|
||||
table->glfwGetFrameBufferSize = glfwGetFramebufferSize;
|
||||
table->glfwGetGamepadName = glfwGetGamepadName;
|
||||
table->glfwGetGamepadState = glfwGetGamepadState;
|
||||
table->glfwGetGammaRamp = glfwGetGammaRamp;
|
||||
table->glfwGetInputMode = glfwGetInputMode;
|
||||
table->glfwGetJoystickAxes = glfwGetJoystickAxes;
|
||||
table->glfwGetJoystickButtons = glfwGetJoystickButtons;
|
||||
table->glfwGetJoystickGUID = glfwGetJoystickGUID;
|
||||
table->glfwGetJoystickHats = glfwGetJoystickHats;
|
||||
table->glfwGetJoystickName = glfwGetJoystickName;
|
||||
table->glfwGetJoystickUserPointer = glfwGetJoystickUserPointer;
|
||||
table->glfwGetKey = glfwGetKey;
|
||||
table->glfwGetKeyName = glfwGetKeyName;
|
||||
table->glfwGetKeyScancode = glfwGetKeyScancode;
|
||||
table->glfwGetMonitorContentScale = glfwGetMonitorContentScale;
|
||||
table->glfwGetMonitorName = glfwGetMonitorName;
|
||||
table->glfwGetMonitorPhysicalSize = glfwGetMonitorPhysicalSize;
|
||||
table->glfwGetMonitorPos = glfwGetMonitorPos;
|
||||
table->glfwGetMonitors = glfwGetMonitors;
|
||||
table->glfwGetMonitorUserPointer = glfwGetMonitorUserPointer;
|
||||
table->glfwGetMonitorWorkarea = glfwGetMonitorWorkarea;
|
||||
table->glfwGetMouseButton = glfwGetMouseButton;
|
||||
table->glfwGetPrimaryMonitor = glfwGetPrimaryMonitor;
|
||||
table->glfwGetProcAddress = glfwGetProcAddress;
|
||||
table->glfwGetRequiredInstanceExtensions = glfwGetRequiredInstanceExtensions;
|
||||
table->glfwGetTime = glfwGetTime;
|
||||
table->glfwGetTimerFrequency = glfwGetTimerFrequency;
|
||||
table->glfwGetTimerValue = glfwGetTimerValue;
|
||||
table->glfwGetVersion = glfwGetVersion;
|
||||
table->glfwGetVersionString = glfwGetVersionString;
|
||||
table->glfwGetVideoMode = glfwGetVideoMode;
|
||||
table->glfwGetVideoModes = glfwGetVideoModes;
|
||||
table->glfwGetWindowAttrib = glfwGetWindowAttrib;
|
||||
table->glfwGetWindowContentScale = glfwGetWindowContentScale;
|
||||
table->glfwGetWindowFrameSize = glfwGetWindowFrameSize;
|
||||
table->glfwGetWindowMonitor = glfwGetWindowMonitor;
|
||||
table->glfwGetWindowOpacity = glfwGetWindowOpacity;
|
||||
table->glfwGetWindowPos = glfwGetWindowPos;
|
||||
table->glfwGetWindowSize = glfwGetWindowSize;
|
||||
table->glfwGetWindowUserPointer = glfwGetWindowUserPointer;
|
||||
table->glfwHideWindow = glfwHideWindow;
|
||||
table->glfwIconifyWindow = glfwIconifyWindow;
|
||||
table->glfwInit = glfwInit;
|
||||
table->glfwInitHint = glfwInitHint;
|
||||
table->glfwJoystickIsGamePad = glfwJoystickIsGamepad;
|
||||
table->glfwJoystickPresent = glfwJoystickPresent;
|
||||
table->glfwMakeContextCurrent = glfwMakeContextCurrent;
|
||||
table->glfwMaximizeWindow = glfwMaximizeWindow;
|
||||
table->glfwPollEvents = glfwPollEvents;
|
||||
table->glfwPostEmptyEvent = glfwPostEmptyEvent;
|
||||
table->glfwRawMouseMotionSupported = glfwRawMouseMotionSupported;
|
||||
table->glfwRequestWindowAttention = glfwRequestWindowAttention;
|
||||
table->glfwRestoreWindow = glfwRestoreWindow;
|
||||
table->glfwSetCharCallback = glfwSetCharCallback;
|
||||
table->glfwSetCharModsCallback = glfwSetCharModsCallback;
|
||||
table->glfwSetClipboardString = glfwSetClipboardString;
|
||||
table->glfwSetCursor = glfwSetCursor;
|
||||
table->glfwSetCursorEnterCallback = glfwSetCursorEnterCallback;
|
||||
table->glfwSetCursorPos = glfwSetCursorPos;
|
||||
table->glfwSetCursorPosCallback = glfwSetCursorPosCallback;
|
||||
table->glfwSetDropCallback = glfwSetDropCallback;
|
||||
table->glfwSetErrorCallback = glfwSetErrorCallback;
|
||||
table->glfwSetFramebufferSizeCallback = glfwSetFramebufferSizeCallback;
|
||||
table->glfwSetGamma = glfwSetGamma;
|
||||
table->glfwSetGammaRamp = glfwSetGammaRamp;
|
||||
table->glfwSetInputMode = glfwSetInputMode;
|
||||
table->glfwSetJoystickCallback = glfwSetJoystickCallback;
|
||||
table->glfwSetJoystickUserPointer = glfwSetJoystickUserPointer;
|
||||
table->glfwSetKeyCallback = glfwSetKeyCallback;
|
||||
table->glfwSetMonitorCallback = glfwSetMonitorCallback;
|
||||
table->glfwSetMonitorUserPointer = glfwSetMonitorUserPointer;
|
||||
table->glfwSetMouseButtonCallback = glfwSetMouseButtonCallback;
|
||||
table->glfwSetScrollCallback = glfwSetScrollCallback;
|
||||
table->glfwSetTime = glfwSetTime;
|
||||
table->glfwSetWindowAspectRatio = glfwSetWindowAspectRatio;
|
||||
table->glfwSetWindowAttrib = glfwSetWindowAttrib;
|
||||
table->glfwSetWindowCloseCallback = glfwSetWindowCloseCallback;
|
||||
table->glfwSetWindowContentScaleCallback = glfwSetWindowContentScaleCallback;
|
||||
table->glfwSetWindowFocusCallback = glfwSetWindowFocusCallback;
|
||||
table->glfwSetWindowIcon = glfwSetWindowIcon;
|
||||
table->glfwSetWindowIconifyCallback = glfwSetWindowIconifyCallback;
|
||||
table->glfwSetWindowMaximizeCallback = glfwSetWindowMaximizeCallback;
|
||||
table->glfwSetWindowMonitor = glfwSetWindowMonitor;
|
||||
table->glfwSetWindowOpacity = glfwSetWindowOpacity;
|
||||
table->glfwSetWindowPos = glfwSetWindowPos;
|
||||
table->glfwSetWindowPosCallback = glfwSetWindowPosCallback;
|
||||
table->glfwSetWindowRefreshCallback = glfwSetWindowRefreshCallback;
|
||||
table->glfwSetWindowShouldClose = glfwSetWindowShouldClose;
|
||||
table->glfwSetWindowSize = glfwSetWindowSize;
|
||||
table->glfwSetWindowSizeCallback = glfwSetWindowSizeCallback;
|
||||
table->glfwSetWindowSizeLimits = glfwSetWindowSizeLimits;
|
||||
table->glfwSetWindowTitle = glfwSetWindowTitle;
|
||||
table->glfwSetWindowUserPointer = glfwSetWindowUserPointer;
|
||||
table->glfwShowWindow = glfwShowWindow;
|
||||
table->glfwSwapBuffers = glfwSwapBuffers;
|
||||
table->glfwSwapInterval = glfwSwapInterval;
|
||||
table->glfwTerminate = glfwTerminate;
|
||||
table->glfwUpdateGamePadMappings = glfwUpdateGamepadMappings;
|
||||
table->glfwVulkanSupported = glfwVulkanSupported;
|
||||
table->glfwWaitEvents = glfwWaitEvents;
|
||||
table->glfwWaitEventsTimeout = glfwWaitEventsTimeout;
|
||||
table->glfwWindowHint = glfwWindowHint;
|
||||
table->glfwWindowHintString = glfwWindowHintString;
|
||||
table->glfwWindowShouldClose = glfwWindowShouldClose;
|
||||
}
|
||||
|
||||
@@ -1,149 +1,149 @@
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "StgSharpNative.h"
|
||||
#include "sn_intrinsic.h"
|
||||
#include "sn_intrincontext.x86.h"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#include <intrin.h>
|
||||
#include <isa_availability.h>
|
||||
#else
|
||||
#include <cpuid.h>
|
||||
#endif // _MSC_VER
|
||||
|
||||
PRIVATE void load_intrinsic_sse(sn_intrinsic *context, SIMDID id);
|
||||
PRIVATE void load_intrinsic_avx(sn_intrinsic *context, SIMDID id);
|
||||
PRIVATE void load_intrinsic_512(sn_intrinsic *context, SIMDID id);
|
||||
|
||||
SN_API SIMDID load_intrinsic_function(void *intrinsic_context)
|
||||
{
|
||||
sn_null_assert(intrinsic_context);
|
||||
|
||||
SIMDID simdid = sn_get_simd_level();
|
||||
|
||||
sn_intrinsic *context = (sn_intrinsic *)intrinsic_context;
|
||||
|
||||
switch (simdid.make_byte[1]) {
|
||||
case SIMDID_MAIN_LVL_SSE:
|
||||
load_intrinsic_sse(context, simdid);
|
||||
break;
|
||||
case SIMDID_MAIN_LVL_AVX2:
|
||||
load_intrinsic_avx(context, simdid);
|
||||
break;
|
||||
case SIMDID_MAIN_LVL_AVX512:
|
||||
load_intrinsic_512(context, simdid);
|
||||
break;
|
||||
}
|
||||
return simdid;
|
||||
}
|
||||
|
||||
void load_intrinsic_sse(sn_intrinsic *context, SIMDID id)
|
||||
{
|
||||
context->city_hash_simplify = city_hash_simplify_sse;
|
||||
context->factorial_simd = factorial_simd_sse;
|
||||
context->index_pair = index_pair_sse;
|
||||
|
||||
context->mat[F32].buffer_add = BUF_PROC(float, sse, , add);
|
||||
context->mat[F32].buffer_fill = BUF_PROC(float, sse, , fill);
|
||||
context->mat[F32].buffer_scalar_mul = BUF_PROC(float, sse, , scalar_mul);
|
||||
context->mat[F32].buffer_sub = BUF_PROC(float, sse, , sub);
|
||||
context->mat[F32].buffer_transpose = KER_PROC(float, sse, , transpose);
|
||||
context->mat[F32].build_panel = NULL;
|
||||
context->mat[F32].clear_panel = PNL_PROC(float, sse, , clear);
|
||||
context->mat[F32].ker_fma = KER_PROC(float, sse, , fma);
|
||||
context->mat[F32].ker_tile_fma = KERTILE_PROC(float, sse, , fma);
|
||||
context->mat[F32].pivot = NULL;
|
||||
context->mat[F32].store_panel = NULL;
|
||||
|
||||
context->mat[F64].buffer_add = BUF_PROC(double, sse, , add);
|
||||
context->mat[F64].buffer_fill = BUF_PROC(double, sse, , fill);
|
||||
context->mat[F64].buffer_scalar_mul = BUF_PROC(double, sse, , scalar_mul);
|
||||
context->mat[F64].buffer_sub = BUF_PROC(double, sse, , sub);
|
||||
context->mat[F64].buffer_transpose = NULL;
|
||||
context->mat[F64].build_panel = NULL;
|
||||
context->mat[F64].clear_panel = PNL_PROC(double, sse, , clear);
|
||||
context->mat[F64].ker_fma = KER_PROC(double, sse, , fma);
|
||||
context->mat[F64].ker_tile_fma = KERTILE_PROC(double, sse, , fma);
|
||||
context->mat[F64].pivot = NULL;
|
||||
context->mat[F64].store_panel = NULL;
|
||||
|
||||
context->vec_f32_normalize_3 = f32_normalize;
|
||||
}
|
||||
|
||||
void load_intrinsic_avx(sn_intrinsic *context, SIMDID id)
|
||||
{
|
||||
char avx_seg = id.make_byte[5];
|
||||
char is_fma = (avx_seg & 1 << 3) != 0;
|
||||
char is_f16c = (avx_seg & 1 << 4) != 0;
|
||||
|
||||
context->city_hash_simplify = city_hash_simplify_sse;
|
||||
context->factorial_simd = factorial_simd_sse;
|
||||
context->index_pair = index_pair_sse;
|
||||
|
||||
context->mat[F32].buffer_add = BUF_PROC(float, avx, , add);
|
||||
context->mat[F32].buffer_fill = BUF_PROC(float, avx, , fill);
|
||||
context->mat[F32].buffer_scalar_mul = BUF_PROC(float, avx, , scalar_mul);
|
||||
context->mat[F32].buffer_sub = BUF_PROC(float, avx, , sub);
|
||||
context->mat[F32].buffer_transpose = KER_PROC(float, avx, , transpose);
|
||||
context->mat[F32].build_panel = BUILD_PANEL(avx, float);
|
||||
context->mat[F32].clear_panel = PNL_PROC(float, avx, , clear);
|
||||
context->mat[F32].ker_fma = is_fma ? KER_PROC(float, avx, , fma) :
|
||||
KER_PROC(float, avx, _fma, fma);
|
||||
context->mat[F32].ker_tile_fma = is_fma ? KERTILE_PROC(float, avx, , fma) :
|
||||
KERTILE_PROC(float, avx, _fma, fma);
|
||||
context->mat[F32].pivot = NULL;
|
||||
context->mat[F32].store_panel = STORE_PANEL(avx, float);
|
||||
|
||||
context->mat[F64].buffer_add = BUF_PROC(double, avx, , add);
|
||||
context->mat[F64].buffer_fill = BUF_PROC(double, avx, , fill);
|
||||
context->mat[F64].buffer_scalar_mul = BUF_PROC(double, avx, , scalar_mul);
|
||||
context->mat[F64].buffer_sub = BUF_PROC(double, avx, , sub);
|
||||
context->mat[F64].buffer_transpose = NULL;
|
||||
context->mat[F64].build_panel = NULL;
|
||||
context->mat[F64].clear_panel = PNL_PROC(double, avx, , clear);
|
||||
context->mat[F64].ker_fma = is_fma ? KER_PROC(double, avx, , fma) :
|
||||
KER_PROC(double, avx, _fma, fma);
|
||||
context->mat[F64].ker_tile_fma = is_fma ? KERTILE_PROC(double, avx, , fma) :
|
||||
KERTILE_PROC(double, avx, _fma, fma);
|
||||
context->mat[F64].pivot = NULL;
|
||||
context->mat[F64].store_panel = NULL;
|
||||
|
||||
context->vec_f32_normalize_3 = f32_normalize;
|
||||
}
|
||||
|
||||
void load_intrinsic_512(sn_intrinsic *context, SIMDID id)
|
||||
{
|
||||
context->city_hash_simplify = city_hash_simplify_sse;
|
||||
context->factorial_simd = factorial_simd_sse;
|
||||
context->index_pair = index_pair_sse;
|
||||
|
||||
context->mat[F32].buffer_add = BUF_PROC(float, 512, , add);
|
||||
context->mat[F32].buffer_fill = BUF_PROC(float, 512, , fill);
|
||||
context->mat[F32].buffer_scalar_mul = BUF_PROC(float, 512, , scalar_mul);
|
||||
context->mat[F32].buffer_sub = BUF_PROC(float, 512, , sub);
|
||||
context->mat[F32].buffer_transpose = KER_PROC(float, 512, , transpose);
|
||||
context->mat[F32].build_panel = BUILD_PANEL(512, float);
|
||||
context->mat[F32].clear_panel = PNL_PROC(float, 512, , clear);
|
||||
context->mat[F32].ker_fma = KER_PROC(float, 512, , fma);
|
||||
context->mat[F32].ker_tile_fma = KERTILE_PROC(float, 512, , fma);
|
||||
context->mat[F32].pivot = NULL;
|
||||
context->mat[F32].store_panel = STORE_PANEL(512, float);
|
||||
|
||||
context->mat[F64].buffer_add = BUF_PROC(double, 512, , add);
|
||||
context->mat[F64].buffer_fill = BUF_PROC(double, 512, , fill);
|
||||
context->mat[F64].buffer_scalar_mul = BUF_PROC(double, 512, , scalar_mul);
|
||||
context->mat[F64].buffer_sub = BUF_PROC(double, 512, , sub);
|
||||
context->mat[F64].buffer_transpose = NULL;
|
||||
context->mat[F64].build_panel = BUILD_PANEL(512, double);
|
||||
context->mat[F64].clear_panel = PNL_PROC(double, 512, , clear);
|
||||
context->mat[F64].ker_fma = KER_PROC(double, 512, , fma);
|
||||
context->mat[F64].ker_tile_fma = KERTILE_PROC(double, 512, , fma);
|
||||
context->mat[F64].pivot = NULL;
|
||||
context->mat[F64].store_panel = STORE_PANEL(512, double);
|
||||
|
||||
context->vec_f32_normalize_3 = f32_normalize;
|
||||
}
|
||||
|
||||
#endif
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "StgSharpNative.h"
|
||||
#include "sn_intrinsic.h"
|
||||
#include "sn_intrincontext.x86.h"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#include <intrin.h>
|
||||
#include <isa_availability.h>
|
||||
#else
|
||||
#include <cpuid.h>
|
||||
#endif // _MSC_VER
|
||||
|
||||
PRIVATE void load_intrinsic_sse(sn_intrinsic *context, SIMDID id);
|
||||
PRIVATE void load_intrinsic_avx(sn_intrinsic *context, SIMDID id);
|
||||
PRIVATE void load_intrinsic_512(sn_intrinsic *context, SIMDID id);
|
||||
|
||||
SN_API SIMDID load_intrinsic_function(void *intrinsic_context)
|
||||
{
|
||||
sn_null_assert(intrinsic_context);
|
||||
|
||||
SIMDID simdid = sn_get_simd_level();
|
||||
|
||||
sn_intrinsic *context = (sn_intrinsic *)intrinsic_context;
|
||||
|
||||
switch (simdid.make_byte[1]) {
|
||||
case SIMDID_MAIN_LVL_SSE:
|
||||
load_intrinsic_sse(context, simdid);
|
||||
break;
|
||||
case SIMDID_MAIN_LVL_AVX2:
|
||||
load_intrinsic_avx(context, simdid);
|
||||
break;
|
||||
case SIMDID_MAIN_LVL_AVX512:
|
||||
load_intrinsic_512(context, simdid);
|
||||
break;
|
||||
}
|
||||
return simdid;
|
||||
}
|
||||
|
||||
void load_intrinsic_sse(sn_intrinsic *context, SIMDID id)
|
||||
{
|
||||
context->city_hash_simplify = city_hash_simplify_sse;
|
||||
context->factorial_simd = factorial_simd_sse;
|
||||
context->index_pair = index_pair_sse;
|
||||
|
||||
context->mat[F32].buffer_add = BUF_PROC(float, sse, , add);
|
||||
context->mat[F32].buffer_fill = BUF_PROC(float, sse, , fill);
|
||||
context->mat[F32].buffer_scalar_mul = BUF_PROC(float, sse, , scalar_mul);
|
||||
context->mat[F32].buffer_sub = BUF_PROC(float, sse, , sub);
|
||||
context->mat[F32].buffer_transpose = KER_PROC(float, sse, , transpose);
|
||||
context->mat[F32].build_panel = NULL;
|
||||
context->mat[F32].clear_panel = PNL_PROC(float, sse, , clear);
|
||||
context->mat[F32].ker_fma = KER_PROC(float, sse, , fma);
|
||||
context->mat[F32].ker_tile_fma = KERTILE_PROC(float, sse, , fma);
|
||||
context->mat[F32].pivot = NULL;
|
||||
context->mat[F32].store_panel = NULL;
|
||||
|
||||
context->mat[F64].buffer_add = BUF_PROC(double, sse, , add);
|
||||
context->mat[F64].buffer_fill = BUF_PROC(double, sse, , fill);
|
||||
context->mat[F64].buffer_scalar_mul = BUF_PROC(double, sse, , scalar_mul);
|
||||
context->mat[F64].buffer_sub = BUF_PROC(double, sse, , sub);
|
||||
context->mat[F64].buffer_transpose = NULL;
|
||||
context->mat[F64].build_panel = NULL;
|
||||
context->mat[F64].clear_panel = PNL_PROC(double, sse, , clear);
|
||||
context->mat[F64].ker_fma = KER_PROC(double, sse, , fma);
|
||||
context->mat[F64].ker_tile_fma = KERTILE_PROC(double, sse, , fma);
|
||||
context->mat[F64].pivot = NULL;
|
||||
context->mat[F64].store_panel = NULL;
|
||||
|
||||
context->vec_f32_normalize_3 = f32_normalize;
|
||||
}
|
||||
|
||||
void load_intrinsic_avx(sn_intrinsic *context, SIMDID id)
|
||||
{
|
||||
char avx_seg = id.make_byte[5];
|
||||
char is_fma = (avx_seg & 1 << 3) != 0;
|
||||
char is_f16c = (avx_seg & 1 << 4) != 0;
|
||||
|
||||
context->city_hash_simplify = city_hash_simplify_sse;
|
||||
context->factorial_simd = factorial_simd_sse;
|
||||
context->index_pair = index_pair_sse;
|
||||
|
||||
context->mat[F32].buffer_add = BUF_PROC(float, avx, , add);
|
||||
context->mat[F32].buffer_fill = BUF_PROC(float, avx, , fill);
|
||||
context->mat[F32].buffer_scalar_mul = BUF_PROC(float, avx, , scalar_mul);
|
||||
context->mat[F32].buffer_sub = BUF_PROC(float, avx, , sub);
|
||||
context->mat[F32].buffer_transpose = KER_PROC(float, avx, , transpose);
|
||||
context->mat[F32].build_panel = BUILD_PANEL(avx, float);
|
||||
context->mat[F32].clear_panel = PNL_PROC(float, avx, , clear);
|
||||
context->mat[F32].ker_fma = is_fma ? KER_PROC(float, avx, , fma) :
|
||||
KER_PROC(float, avx, _fma, fma);
|
||||
context->mat[F32].ker_tile_fma = is_fma ? KERTILE_PROC(float, avx, , fma) :
|
||||
KERTILE_PROC(float, avx, _fma, fma);
|
||||
context->mat[F32].pivot = NULL;
|
||||
context->mat[F32].store_panel = STORE_PANEL(avx, float);
|
||||
|
||||
context->mat[F64].buffer_add = BUF_PROC(double, avx, , add);
|
||||
context->mat[F64].buffer_fill = BUF_PROC(double, avx, , fill);
|
||||
context->mat[F64].buffer_scalar_mul = BUF_PROC(double, avx, , scalar_mul);
|
||||
context->mat[F64].buffer_sub = BUF_PROC(double, avx, , sub);
|
||||
context->mat[F64].buffer_transpose = NULL;
|
||||
context->mat[F64].build_panel = NULL;
|
||||
context->mat[F64].clear_panel = PNL_PROC(double, avx, , clear);
|
||||
context->mat[F64].ker_fma = is_fma ? KER_PROC(double, avx, , fma) :
|
||||
KER_PROC(double, avx, _fma, fma);
|
||||
context->mat[F64].ker_tile_fma = is_fma ? KERTILE_PROC(double, avx, , fma) :
|
||||
KERTILE_PROC(double, avx, _fma, fma);
|
||||
context->mat[F64].pivot = NULL;
|
||||
context->mat[F64].store_panel = NULL;
|
||||
|
||||
context->vec_f32_normalize_3 = f32_normalize;
|
||||
}
|
||||
|
||||
void load_intrinsic_512(sn_intrinsic *context, SIMDID id)
|
||||
{
|
||||
context->city_hash_simplify = city_hash_simplify_sse;
|
||||
context->factorial_simd = factorial_simd_sse;
|
||||
context->index_pair = index_pair_sse;
|
||||
|
||||
context->mat[F32].buffer_add = BUF_PROC(float, 512, , add);
|
||||
context->mat[F32].buffer_fill = BUF_PROC(float, 512, , fill);
|
||||
context->mat[F32].buffer_scalar_mul = BUF_PROC(float, 512, , scalar_mul);
|
||||
context->mat[F32].buffer_sub = BUF_PROC(float, 512, , sub);
|
||||
context->mat[F32].buffer_transpose = KER_PROC(float, 512, , transpose);
|
||||
context->mat[F32].build_panel = BUILD_PANEL(512, float);
|
||||
context->mat[F32].clear_panel = PNL_PROC(float, 512, , clear);
|
||||
context->mat[F32].ker_fma = KER_PROC(float, 512, , fma);
|
||||
context->mat[F32].ker_tile_fma = KERTILE_PROC(float, 512, , fma);
|
||||
context->mat[F32].pivot = NULL;
|
||||
context->mat[F32].store_panel = STORE_PANEL(512, float);
|
||||
|
||||
context->mat[F64].buffer_add = BUF_PROC(double, 512, , add);
|
||||
context->mat[F64].buffer_fill = BUF_PROC(double, 512, , fill);
|
||||
context->mat[F64].buffer_scalar_mul = BUF_PROC(double, 512, , scalar_mul);
|
||||
context->mat[F64].buffer_sub = BUF_PROC(double, 512, , sub);
|
||||
context->mat[F64].buffer_transpose = NULL;
|
||||
context->mat[F64].build_panel = BUILD_PANEL(512, double);
|
||||
context->mat[F64].clear_panel = PNL_PROC(double, 512, , clear);
|
||||
context->mat[F64].ker_fma = KER_PROC(double, 512, , fma);
|
||||
context->mat[F64].ker_tile_fma = KERTILE_PROC(double, 512, , fma);
|
||||
context->mat[F64].pivot = NULL;
|
||||
context->mat[F64].store_panel = STORE_PANEL(512, double);
|
||||
|
||||
context->vec_f32_normalize_3 = f32_normalize;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,100 +1,100 @@
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrinsic.h"
|
||||
#include "sn_intrincontext.x86.h"
|
||||
|
||||
DECLARE_PNL_PROC_ANS(float, sse, , clear)
|
||||
{
|
||||
register __m128 zero = _mm_setzero_ps();
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
PANEL_COL_VEC((*ans), i, 0) = zero;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_PNL_PROC_ANS(float, avx, , clear)
|
||||
{
|
||||
register __m256 zero = _mm256_setzero_ps();
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
PANEL_COL_VEC((*ans), i, 0) = zero;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_PNL_PROC_ANS(float, 512, , clear)
|
||||
{
|
||||
register __m512 zero = _mm512_setzero_ps();
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
PANEL_COL_VEC((*ans), i, 0) = zero;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_PNL_PROC_ANS(double, sse, , clear)
|
||||
{
|
||||
register __m128 zero = _mm_setzero_ps();
|
||||
PANEL_COL_VEC((*ans), 0, 0) = zero;
|
||||
PANEL_COL_VEC((*ans), 1, 0) = zero;
|
||||
PANEL_COL_VEC((*ans), 2, 0) = zero;
|
||||
PANEL_COL_VEC((*ans), 3, 0) = zero;
|
||||
}
|
||||
|
||||
DECLARE_PNL_PROC_ANS(double, avx, , clear)
|
||||
{
|
||||
register __m256 zero = _mm256_setzero_ps();
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
PANEL_COL_VEC((*ans), i, 0) = zero;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_PNL_PROC_ANS(double, 512, , clear)
|
||||
{
|
||||
register __m512 zero = _mm512_setzero_ps();
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
PANEL_COL_VEC((*ans), i, 0) = zero;
|
||||
}
|
||||
}
|
||||
|
||||
// Matrix transpose implementations
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, sse, ,transpose)
|
||||
{
|
||||
register __m128 col0 = right->f32_x[0];
|
||||
register __m128 col1 = right->f32_x[1];
|
||||
register __m128 col2 = right->f32_x[2];
|
||||
register __m128 col3 = right->f32_x[3];
|
||||
register __m128 tmp0 = _mm_unpacklo_ps(col0, col1);
|
||||
register __m128 tmp1 = _mm_unpackhi_ps(col0, col1);
|
||||
register __m128 tmp2 = _mm_unpacklo_ps(col2, col3);
|
||||
register __m128 tmp3 = _mm_unpackhi_ps(col2, col3);
|
||||
|
||||
ans->f32_x[0] = _mm_movelh_ps(tmp0, tmp2);
|
||||
ans->f32_x[1] = _mm_movehl_ps(tmp2, tmp0);
|
||||
ans->f32_x[2] = _mm_movelh_ps(tmp1, tmp3);
|
||||
ans->f32_x[3] = _mm_movehl_ps(tmp3, tmp1);
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, avx, ,transpose)
|
||||
{
|
||||
register __m256 col_low = right->f32_y[0];
|
||||
register __m256 col_high = right->f32_y[1];
|
||||
|
||||
register __m256 unpack_low = _mm256_unpacklo_ps(col_low, col_high);
|
||||
register __m256 unpack_high = _mm256_unpackhi_ps(col_low, col_high);
|
||||
|
||||
col_low = _mm256_permute2f128_ps(unpack_low, unpack_high, 0x20);
|
||||
col_high = _mm256_permute2f128_ps(unpack_low, unpack_high, 0x31);
|
||||
|
||||
ans->f32_y[0] = _mm256_shuffle_ps(col_high, col_low, _MM_SHUFFLE(2, 0, 2, 0));
|
||||
ans->f32_y[1] = _mm256_shuffle_ps(col_high, col_low, _MM_SHUFFLE(3, 1, 3, 1));
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, 512, ,transpose)
|
||||
{
|
||||
register __m512 matrix = right->f32_z[0];
|
||||
|
||||
const __m512i transpose_indices =
|
||||
_mm512_setr_epi32(0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15);
|
||||
|
||||
ans->f32_z[0] = _mm512_permutexvar_ps(transpose_indices, matrix);
|
||||
}
|
||||
|
||||
#endif
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrinsic.h"
|
||||
#include "sn_intrincontext.x86.h"
|
||||
|
||||
DECLARE_PNL_PROC_ANS(float, sse, , clear)
|
||||
{
|
||||
register __m128 zero = _mm_setzero_ps();
|
||||
for (size_t i = 0; i < 4; i++) {
|
||||
PANEL_COL_VEC((*ans), i, 0) = zero;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_PNL_PROC_ANS(float, avx, , clear)
|
||||
{
|
||||
register __m256 zero = _mm256_setzero_ps();
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
PANEL_COL_VEC((*ans), i, 0) = zero;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_PNL_PROC_ANS(float, 512, , clear)
|
||||
{
|
||||
register __m512 zero = _mm512_setzero_ps();
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
PANEL_COL_VEC((*ans), i, 0) = zero;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_PNL_PROC_ANS(double, sse, , clear)
|
||||
{
|
||||
register __m128 zero = _mm_setzero_ps();
|
||||
PANEL_COL_VEC((*ans), 0, 0) = zero;
|
||||
PANEL_COL_VEC((*ans), 1, 0) = zero;
|
||||
PANEL_COL_VEC((*ans), 2, 0) = zero;
|
||||
PANEL_COL_VEC((*ans), 3, 0) = zero;
|
||||
}
|
||||
|
||||
DECLARE_PNL_PROC_ANS(double, avx, , clear)
|
||||
{
|
||||
register __m256 zero = _mm256_setzero_ps();
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
PANEL_COL_VEC((*ans), i, 0) = zero;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_PNL_PROC_ANS(double, 512, , clear)
|
||||
{
|
||||
register __m512 zero = _mm512_setzero_ps();
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
PANEL_COL_VEC((*ans), i, 0) = zero;
|
||||
}
|
||||
}
|
||||
|
||||
// Matrix transpose implementations
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, sse, ,transpose)
|
||||
{
|
||||
register __m128 col0 = right->f32_x[0];
|
||||
register __m128 col1 = right->f32_x[1];
|
||||
register __m128 col2 = right->f32_x[2];
|
||||
register __m128 col3 = right->f32_x[3];
|
||||
register __m128 tmp0 = _mm_unpacklo_ps(col0, col1);
|
||||
register __m128 tmp1 = _mm_unpackhi_ps(col0, col1);
|
||||
register __m128 tmp2 = _mm_unpacklo_ps(col2, col3);
|
||||
register __m128 tmp3 = _mm_unpackhi_ps(col2, col3);
|
||||
|
||||
ans->f32_x[0] = _mm_movelh_ps(tmp0, tmp2);
|
||||
ans->f32_x[1] = _mm_movehl_ps(tmp2, tmp0);
|
||||
ans->f32_x[2] = _mm_movelh_ps(tmp1, tmp3);
|
||||
ans->f32_x[3] = _mm_movehl_ps(tmp3, tmp1);
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, avx, ,transpose)
|
||||
{
|
||||
register __m256 col_low = right->f32_y[0];
|
||||
register __m256 col_high = right->f32_y[1];
|
||||
|
||||
register __m256 unpack_low = _mm256_unpacklo_ps(col_low, col_high);
|
||||
register __m256 unpack_high = _mm256_unpackhi_ps(col_low, col_high);
|
||||
|
||||
col_low = _mm256_permute2f128_ps(unpack_low, unpack_high, 0x20);
|
||||
col_high = _mm256_permute2f128_ps(unpack_low, unpack_high, 0x31);
|
||||
|
||||
ans->f32_y[0] = _mm256_shuffle_ps(col_high, col_low, _MM_SHUFFLE(2, 0, 2, 0));
|
||||
ans->f32_y[1] = _mm256_shuffle_ps(col_high, col_low, _MM_SHUFFLE(3, 1, 3, 1));
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, 512, ,transpose)
|
||||
{
|
||||
register __m512 matrix = right->f32_z[0];
|
||||
|
||||
const __m512i transpose_indices =
|
||||
_mm512_setr_epi32(0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15);
|
||||
|
||||
ans->f32_z[0] = _mm512_permutexvar_ps(transpose_indices, matrix);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,324 +1,324 @@
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrinsic.h"
|
||||
#include "sn_intrincontext.x86.h"
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(float, sse, ,fill)
|
||||
{
|
||||
register __m128 vec = _mm_set_ps1(((float *)(scalar->data))[0]);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ans[i].f32_x[0] = vec;
|
||||
ans[i].f32_x[1] = vec;
|
||||
ans[i].f32_x[2] = vec;
|
||||
ans[i].f32_x[3] = vec;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(float, avx, ,fill)
|
||||
{
|
||||
register __m256 vec = _mm256_broadcast_ss(((float *)(scalar->data)));
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ans[i].f32_y[0] = vec;
|
||||
ans[i].f32_y[1] = vec;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(float, 512, ,fill)
|
||||
{
|
||||
register __m512 vec = _mm512_broadcastss_ps(((__m128 *)(scalar->data))[0]);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ans[i].f32_z[0] = vec;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(double, sse, ,fill)
|
||||
{
|
||||
register __m128d vec = _mm_set1_pd(((double *)(scalar->data))[0]);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ans[i].f64_x[0] = vec;
|
||||
ans[i].f64_x[1] = vec;
|
||||
ans[i].f64_x[2] = vec;
|
||||
ans[i].f64_x[3] = vec;
|
||||
ans[i].f64_x[4] = vec;
|
||||
ans[i].f64_x[5] = vec;
|
||||
ans[i].f64_x[6] = vec;
|
||||
ans[i].f64_x[7] = vec;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(double, avx, ,fill)
|
||||
{
|
||||
register __m256d vec = _mm256_broadcast_sd(((double *)(scalar->data)));
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ans[i].f64_y[0] = vec;
|
||||
ans[i].f64_y[1] = vec;
|
||||
ans[i].f64_y[2] = vec;
|
||||
ans[i].f64_y[3] = vec;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(double, 512, ,fill)
|
||||
{
|
||||
register __m512d vec = _mm512_broadcastsd_pd(_mm_loadu_pd(scalar));
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ans[i].f64_z[0] = vec;
|
||||
ans[i].f64_z[1] = vec;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, sse, ,add)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m128 c0 = _mm_add_ps(left[i].f32_x[0], right[i].f32_x[0]);
|
||||
register __m128 c1 = _mm_add_ps(left[i].f32_x[1], right[i].f32_x[1]);
|
||||
register __m128 c2 = _mm_add_ps(left[i].f32_x[2], right[i].f32_x[2]);
|
||||
register __m128 c3 = _mm_add_ps(left[i].f32_x[3], right[i].f32_x[3]);
|
||||
|
||||
ans[i].f32_x[0] = c0;
|
||||
ans[i].f32_x[1] = c1;
|
||||
ans[i].f32_x[2] = c2;
|
||||
ans[i].f32_x[3] = c3;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, avx, ,add)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
size_t s = sizeof(MAT_KERNEL(float));
|
||||
register __m256 c0 = _mm256_add_ps(left[i].f32_y[0], right[i].f32_y[0]);
|
||||
register __m256 c1 = _mm256_add_ps(left[i].f32_y[1], right[i].f32_y[1]);
|
||||
ans[i].f32_y[0] = c0;
|
||||
ans[i].f32_y[1] = c1;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, 512, ,add)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m512 c0 = _mm512_add_ps(left[i].f32_z[0], right[i].f32_z[0]);
|
||||
ans[i].f32_z[0] = c0;
|
||||
}
|
||||
}
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, sse, ,add)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m128d c0 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[0]),
|
||||
_mm_castps_pd(right[i].f32_x[0]));
|
||||
register __m128d c1 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[1]),
|
||||
_mm_castps_pd(right[i].f32_x[1]));
|
||||
register __m128d c2 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[2]),
|
||||
_mm_castps_pd(right[i].f32_x[2]));
|
||||
register __m128d c3 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[3]),
|
||||
_mm_castps_pd(right[i].f32_x[3]));
|
||||
register __m128d c4 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[4]),
|
||||
_mm_castps_pd(right[i].f32_x[4]));
|
||||
register __m128d c5 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[5]),
|
||||
_mm_castps_pd(right[i].f32_x[5]));
|
||||
register __m128d c6 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[6]),
|
||||
_mm_castps_pd(right[i].f32_x[6]));
|
||||
register __m128d c7 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[7]),
|
||||
_mm_castps_pd(right[i].f32_x[7]));
|
||||
|
||||
ans[i].f32_x[0] = _mm_castpd_ps(c0);
|
||||
ans[i].f32_x[1] = _mm_castpd_ps(c1);
|
||||
ans[i].f32_x[2] = _mm_castpd_ps(c2);
|
||||
ans[i].f32_x[3] = _mm_castpd_ps(c3);
|
||||
ans[i].f32_x[4] = _mm_castpd_ps(c4);
|
||||
ans[i].f32_x[5] = _mm_castpd_ps(c5);
|
||||
ans[i].f32_x[6] = _mm_castpd_ps(c6);
|
||||
ans[i].f32_x[7] = _mm_castpd_ps(c7);
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, avx, ,add)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
size_t s = sizeof(MAT_KERNEL(float));
|
||||
register __m256d c0 = _mm256_add_pd(left[i].f64_y[0], right[i].f64_y[0]);
|
||||
register __m256d c1 = _mm256_add_pd(left[i].f64_y[1], right[i].f64_y[1]);
|
||||
register __m256d c2 = _mm256_add_pd(left[i].f64_y[0], right[i].f64_y[0]);
|
||||
register __m256d c3 = _mm256_add_pd(left[i].f64_y[1], right[i].f64_y[1]);
|
||||
ans[i].f64_y[0] = c0;
|
||||
ans[i].f64_y[1] = c1;
|
||||
ans[i].f64_y[2] = c2;
|
||||
ans[i].f64_y[3] = c3;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, 512, ,add)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m512d c0 = _mm512_add_pd(left[i].f64_z[0], right[i].f64_z[0]);
|
||||
register __m512d c1 = _mm512_add_pd(left[i].f64_z[1], right[i].f64_z[1]);
|
||||
ans[i].f64_z[0] = c0;
|
||||
ans[i].f64_z[1] = c1;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, sse, ,sub)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m128 c0 = _mm_sub_ps(left[i].f32_x[0], right[i].f32_x[0]);
|
||||
register __m128 c1 = _mm_sub_ps(left[i].f32_x[1], right[i].f32_x[1]);
|
||||
register __m128 c2 = _mm_sub_ps(left[i].f32_x[2], right[i].f32_x[2]);
|
||||
register __m128 c3 = _mm_sub_ps(left[i].f32_x[3], right[i].f32_x[3]);
|
||||
|
||||
ans[i].f32_x[0] = c0;
|
||||
ans[i].f32_x[1] = c1;
|
||||
ans[i].f32_x[2] = c2;
|
||||
ans[i].f32_x[3] = c3;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, avx, ,sub)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m256 c0 = _mm256_sub_ps(left[i].f32_y[0], right[i].f32_y[0]);
|
||||
register __m256 c1 = _mm256_sub_ps(left[i].f32_y[1], right[i].f32_y[1]);
|
||||
ans[i].f32_y[0] = c0;
|
||||
ans[i].f32_y[1] = c1;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, 512, ,sub)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m512 c0 = _mm512_sub_ps(left[i].f32_z[0], right[i].f32_z[0]);
|
||||
ans[i].f32_z[0] = c0;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, sse, ,sub)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m128d c0 = _mm_sub_pd(left[i].f64_x[0], right[i].f64_x[0]);
|
||||
register __m128d c1 = _mm_sub_pd(left[i].f64_x[1], right[i].f64_x[1]);
|
||||
register __m128d c2 = _mm_sub_pd(left[i].f64_x[2], right[i].f64_x[2]);
|
||||
register __m128d c3 = _mm_sub_pd(left[i].f64_x[3], right[i].f64_x[3]);
|
||||
register __m128d c4 = _mm_sub_pd(left[i].f64_x[4], right[i].f64_x[4]);
|
||||
register __m128d c5 = _mm_sub_pd(left[i].f64_x[5], right[i].f64_x[5]);
|
||||
register __m128d c6 = _mm_sub_pd(left[i].f64_x[6], right[i].f64_x[6]);
|
||||
register __m128d c7 = _mm_sub_pd(left[i].f64_x[7], right[i].f64_x[7]);
|
||||
|
||||
ans[i].f64_x[0] = c0;
|
||||
ans[i].f64_x[1] = c1;
|
||||
ans[i].f64_x[2] = c2;
|
||||
ans[i].f64_x[3] = c3;
|
||||
ans[i].f64_x[4] = c4;
|
||||
ans[i].f64_x[5] = c5;
|
||||
ans[i].f64_x[6] = c6;
|
||||
ans[i].f64_x[7] = c7;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, avx, ,sub)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m256 c0 = _mm256_sub_ps(left[i].f32_y[0], right[i].f32_y[0]);
|
||||
register __m256 c1 = _mm256_sub_ps(left[i].f32_y[1], right[i].f32_y[1]);
|
||||
ans[i].f32_y[0] = c0;
|
||||
ans[i].f32_y[1] = c1;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, 512, ,sub)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m512 c0 = _mm512_sub_ps(left[i].f32_z[0], right[i].f32_z[0]);
|
||||
ans[i].f32_z[0] = c0;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, sse, ,scalar_mul)
|
||||
{
|
||||
register __m128 vec = _mm_set_ps1(((float *)(scalar->data))[0]);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m128 c0 = _mm_mul_ps(right[i].f32_x[0], vec);
|
||||
register __m128 c1 = _mm_mul_ps(right[i].f32_x[1], vec);
|
||||
register __m128 c2 = _mm_mul_ps(right[i].f32_x[2], vec);
|
||||
register __m128 c3 = _mm_mul_ps(right[i].f32_x[3], vec);
|
||||
|
||||
ans[i].f32_x[0] = c0;
|
||||
ans[i].f32_x[1] = c1;
|
||||
ans[i].f32_x[2] = c2;
|
||||
ans[i].f32_x[3] = c3;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, avx, ,scalar_mul)
|
||||
{
|
||||
register __m256 vec = _mm256_broadcast_ss(((float *)(scalar->data)));
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m256 c0 = _mm256_mul_ps(right[i].f32_y[0], vec);
|
||||
register __m256 c1 = _mm256_mul_ps(right[i].f32_y[1], vec);
|
||||
|
||||
ans[i].f32_y[0] = c0;
|
||||
ans[i].f32_y[1] = c1;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, 512, ,scalar_mul)
|
||||
{
|
||||
register __m512 vec = _mm512_broadcastss_ps(((__m128 *)(scalar->data))[0]);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m512 c0 = _mm512_mul_ps(right[i].f32_z[0], vec);
|
||||
|
||||
ans[i].f32_z[0] = c0;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(double, sse, ,scalar_mul)
|
||||
{
|
||||
register __m128d vec = _mm_set1_pd(((double *)(scalar->data))[0]);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m128d c0 = _mm_mul_pd(right[i].f64_x[0], vec);
|
||||
register __m128d c1 = _mm_mul_pd(right[i].f64_x[1], vec);
|
||||
register __m128d c2 = _mm_mul_pd(right[i].f64_x[2], vec);
|
||||
register __m128d c3 = _mm_mul_pd(right[i].f64_x[3], vec);
|
||||
register __m128d c4 = _mm_mul_pd(right[i].f64_x[4], vec);
|
||||
register __m128d c5 = _mm_mul_pd(right[i].f64_x[5], vec);
|
||||
register __m128d c6 = _mm_mul_pd(right[i].f64_x[6], vec);
|
||||
register __m128d c7 = _mm_mul_pd(right[i].f64_x[7], vec);
|
||||
|
||||
ans[i].f64_x[0] = c0;
|
||||
ans[i].f64_x[1] = c1;
|
||||
ans[i].f64_x[2] = c2;
|
||||
ans[i].f64_x[3] = c3;
|
||||
ans[i].f64_x[4] = c4;
|
||||
ans[i].f64_x[5] = c5;
|
||||
ans[i].f64_x[6] = c6;
|
||||
ans[i].f64_x[7] = c7;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(double, avx, ,scalar_mul)
|
||||
{
|
||||
register __m256d vec = _mm256_broadcast_sd(((double *)(scalar->data)));
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m256d c0 = _mm256_mul_pd(right[i].f64_y[0], vec);
|
||||
register __m256d c1 = _mm256_mul_pd(right[i].f64_y[1], vec);
|
||||
register __m256d c2 = _mm256_mul_pd(right[i].f64_y[2], vec);
|
||||
register __m256d c3 = _mm256_mul_pd(right[i].f64_y[3], vec);
|
||||
|
||||
ans[i].f64_y[0] = c0;
|
||||
ans[i].f64_y[1] = c1;
|
||||
ans[i].f64_y[2] = c2;
|
||||
ans[i].f64_y[3] = c3;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(double, 512, ,scalar_mul)
|
||||
{
|
||||
register __m512d vec = _mm512_broadcastsd_pd(_mm_load_pd(scalar));
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m512d c0 = _mm512_mul_pd(right[i].f64_z[0], vec);
|
||||
register __m512d c1 = _mm512_mul_pd(right[i].f64_z[1], vec);
|
||||
|
||||
ans[i].f64_z[0] = c0;
|
||||
ans[i].f64_z[1] = c1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrinsic.h"
|
||||
#include "sn_intrincontext.x86.h"
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(float, sse, ,fill)
|
||||
{
|
||||
register __m128 vec = _mm_set_ps1(((float *)(scalar->data))[0]);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ans[i].f32_x[0] = vec;
|
||||
ans[i].f32_x[1] = vec;
|
||||
ans[i].f32_x[2] = vec;
|
||||
ans[i].f32_x[3] = vec;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(float, avx, ,fill)
|
||||
{
|
||||
register __m256 vec = _mm256_broadcast_ss(((float *)(scalar->data)));
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ans[i].f32_y[0] = vec;
|
||||
ans[i].f32_y[1] = vec;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(float, 512, ,fill)
|
||||
{
|
||||
register __m512 vec = _mm512_broadcastss_ps(((__m128 *)(scalar->data))[0]);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ans[i].f32_z[0] = vec;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(double, sse, ,fill)
|
||||
{
|
||||
register __m128d vec = _mm_set1_pd(((double *)(scalar->data))[0]);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ans[i].f64_x[0] = vec;
|
||||
ans[i].f64_x[1] = vec;
|
||||
ans[i].f64_x[2] = vec;
|
||||
ans[i].f64_x[3] = vec;
|
||||
ans[i].f64_x[4] = vec;
|
||||
ans[i].f64_x[5] = vec;
|
||||
ans[i].f64_x[6] = vec;
|
||||
ans[i].f64_x[7] = vec;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(double, avx, ,fill)
|
||||
{
|
||||
register __m256d vec = _mm256_broadcast_sd(((double *)(scalar->data)));
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ans[i].f64_y[0] = vec;
|
||||
ans[i].f64_y[1] = vec;
|
||||
ans[i].f64_y[2] = vec;
|
||||
ans[i].f64_y[3] = vec;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_ANS_SCALAR(double, 512, ,fill)
|
||||
{
|
||||
register __m512d vec = _mm512_broadcastsd_pd(_mm_loadu_pd(scalar));
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
ans[i].f64_z[0] = vec;
|
||||
ans[i].f64_z[1] = vec;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, sse, ,add)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m128 c0 = _mm_add_ps(left[i].f32_x[0], right[i].f32_x[0]);
|
||||
register __m128 c1 = _mm_add_ps(left[i].f32_x[1], right[i].f32_x[1]);
|
||||
register __m128 c2 = _mm_add_ps(left[i].f32_x[2], right[i].f32_x[2]);
|
||||
register __m128 c3 = _mm_add_ps(left[i].f32_x[3], right[i].f32_x[3]);
|
||||
|
||||
ans[i].f32_x[0] = c0;
|
||||
ans[i].f32_x[1] = c1;
|
||||
ans[i].f32_x[2] = c2;
|
||||
ans[i].f32_x[3] = c3;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, avx, ,add)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
size_t s = sizeof(MAT_KERNEL(float));
|
||||
register __m256 c0 = _mm256_add_ps(left[i].f32_y[0], right[i].f32_y[0]);
|
||||
register __m256 c1 = _mm256_add_ps(left[i].f32_y[1], right[i].f32_y[1]);
|
||||
ans[i].f32_y[0] = c0;
|
||||
ans[i].f32_y[1] = c1;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, 512, ,add)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m512 c0 = _mm512_add_ps(left[i].f32_z[0], right[i].f32_z[0]);
|
||||
ans[i].f32_z[0] = c0;
|
||||
}
|
||||
}
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, sse, ,add)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m128d c0 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[0]),
|
||||
_mm_castps_pd(right[i].f32_x[0]));
|
||||
register __m128d c1 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[1]),
|
||||
_mm_castps_pd(right[i].f32_x[1]));
|
||||
register __m128d c2 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[2]),
|
||||
_mm_castps_pd(right[i].f32_x[2]));
|
||||
register __m128d c3 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[3]),
|
||||
_mm_castps_pd(right[i].f32_x[3]));
|
||||
register __m128d c4 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[4]),
|
||||
_mm_castps_pd(right[i].f32_x[4]));
|
||||
register __m128d c5 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[5]),
|
||||
_mm_castps_pd(right[i].f32_x[5]));
|
||||
register __m128d c6 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[6]),
|
||||
_mm_castps_pd(right[i].f32_x[6]));
|
||||
register __m128d c7 = _mm_add_pd(_mm_castps_pd(left[i].f32_x[7]),
|
||||
_mm_castps_pd(right[i].f32_x[7]));
|
||||
|
||||
ans[i].f32_x[0] = _mm_castpd_ps(c0);
|
||||
ans[i].f32_x[1] = _mm_castpd_ps(c1);
|
||||
ans[i].f32_x[2] = _mm_castpd_ps(c2);
|
||||
ans[i].f32_x[3] = _mm_castpd_ps(c3);
|
||||
ans[i].f32_x[4] = _mm_castpd_ps(c4);
|
||||
ans[i].f32_x[5] = _mm_castpd_ps(c5);
|
||||
ans[i].f32_x[6] = _mm_castpd_ps(c6);
|
||||
ans[i].f32_x[7] = _mm_castpd_ps(c7);
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, avx, ,add)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
size_t s = sizeof(MAT_KERNEL(float));
|
||||
register __m256d c0 = _mm256_add_pd(left[i].f64_y[0], right[i].f64_y[0]);
|
||||
register __m256d c1 = _mm256_add_pd(left[i].f64_y[1], right[i].f64_y[1]);
|
||||
register __m256d c2 = _mm256_add_pd(left[i].f64_y[0], right[i].f64_y[0]);
|
||||
register __m256d c3 = _mm256_add_pd(left[i].f64_y[1], right[i].f64_y[1]);
|
||||
ans[i].f64_y[0] = c0;
|
||||
ans[i].f64_y[1] = c1;
|
||||
ans[i].f64_y[2] = c2;
|
||||
ans[i].f64_y[3] = c3;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, 512, ,add)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m512d c0 = _mm512_add_pd(left[i].f64_z[0], right[i].f64_z[0]);
|
||||
register __m512d c1 = _mm512_add_pd(left[i].f64_z[1], right[i].f64_z[1]);
|
||||
ans[i].f64_z[0] = c0;
|
||||
ans[i].f64_z[1] = c1;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, sse, ,sub)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m128 c0 = _mm_sub_ps(left[i].f32_x[0], right[i].f32_x[0]);
|
||||
register __m128 c1 = _mm_sub_ps(left[i].f32_x[1], right[i].f32_x[1]);
|
||||
register __m128 c2 = _mm_sub_ps(left[i].f32_x[2], right[i].f32_x[2]);
|
||||
register __m128 c3 = _mm_sub_ps(left[i].f32_x[3], right[i].f32_x[3]);
|
||||
|
||||
ans[i].f32_x[0] = c0;
|
||||
ans[i].f32_x[1] = c1;
|
||||
ans[i].f32_x[2] = c2;
|
||||
ans[i].f32_x[3] = c3;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, avx, ,sub)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m256 c0 = _mm256_sub_ps(left[i].f32_y[0], right[i].f32_y[0]);
|
||||
register __m256 c1 = _mm256_sub_ps(left[i].f32_y[1], right[i].f32_y[1]);
|
||||
ans[i].f32_y[0] = c0;
|
||||
ans[i].f32_y[1] = c1;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, 512, ,sub)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m512 c0 = _mm512_sub_ps(left[i].f32_z[0], right[i].f32_z[0]);
|
||||
ans[i].f32_z[0] = c0;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, sse, ,sub)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m128d c0 = _mm_sub_pd(left[i].f64_x[0], right[i].f64_x[0]);
|
||||
register __m128d c1 = _mm_sub_pd(left[i].f64_x[1], right[i].f64_x[1]);
|
||||
register __m128d c2 = _mm_sub_pd(left[i].f64_x[2], right[i].f64_x[2]);
|
||||
register __m128d c3 = _mm_sub_pd(left[i].f64_x[3], right[i].f64_x[3]);
|
||||
register __m128d c4 = _mm_sub_pd(left[i].f64_x[4], right[i].f64_x[4]);
|
||||
register __m128d c5 = _mm_sub_pd(left[i].f64_x[5], right[i].f64_x[5]);
|
||||
register __m128d c6 = _mm_sub_pd(left[i].f64_x[6], right[i].f64_x[6]);
|
||||
register __m128d c7 = _mm_sub_pd(left[i].f64_x[7], right[i].f64_x[7]);
|
||||
|
||||
ans[i].f64_x[0] = c0;
|
||||
ans[i].f64_x[1] = c1;
|
||||
ans[i].f64_x[2] = c2;
|
||||
ans[i].f64_x[3] = c3;
|
||||
ans[i].f64_x[4] = c4;
|
||||
ans[i].f64_x[5] = c5;
|
||||
ans[i].f64_x[6] = c6;
|
||||
ans[i].f64_x[7] = c7;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, avx, ,sub)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m256 c0 = _mm256_sub_ps(left[i].f32_y[0], right[i].f32_y[0]);
|
||||
register __m256 c1 = _mm256_sub_ps(left[i].f32_y[1], right[i].f32_y[1]);
|
||||
ans[i].f32_y[0] = c0;
|
||||
ans[i].f32_y[1] = c1;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_LEFT_RIGHT_ANS(double, 512, ,sub)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m512 c0 = _mm512_sub_ps(left[i].f32_z[0], right[i].f32_z[0]);
|
||||
ans[i].f32_z[0] = c0;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, sse, ,scalar_mul)
|
||||
{
|
||||
register __m128 vec = _mm_set_ps1(((float *)(scalar->data))[0]);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m128 c0 = _mm_mul_ps(right[i].f32_x[0], vec);
|
||||
register __m128 c1 = _mm_mul_ps(right[i].f32_x[1], vec);
|
||||
register __m128 c2 = _mm_mul_ps(right[i].f32_x[2], vec);
|
||||
register __m128 c3 = _mm_mul_ps(right[i].f32_x[3], vec);
|
||||
|
||||
ans[i].f32_x[0] = c0;
|
||||
ans[i].f32_x[1] = c1;
|
||||
ans[i].f32_x[2] = c2;
|
||||
ans[i].f32_x[3] = c3;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, avx, ,scalar_mul)
|
||||
{
|
||||
register __m256 vec = _mm256_broadcast_ss(((float *)(scalar->data)));
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m256 c0 = _mm256_mul_ps(right[i].f32_y[0], vec);
|
||||
register __m256 c1 = _mm256_mul_ps(right[i].f32_y[1], vec);
|
||||
|
||||
ans[i].f32_y[0] = c0;
|
||||
ans[i].f32_y[1] = c1;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, 512, ,scalar_mul)
|
||||
{
|
||||
register __m512 vec = _mm512_broadcastss_ps(((__m128 *)(scalar->data))[0]);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m512 c0 = _mm512_mul_ps(right[i].f32_z[0], vec);
|
||||
|
||||
ans[i].f32_z[0] = c0;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(double, sse, ,scalar_mul)
|
||||
{
|
||||
register __m128d vec = _mm_set1_pd(((double *)(scalar->data))[0]);
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m128d c0 = _mm_mul_pd(right[i].f64_x[0], vec);
|
||||
register __m128d c1 = _mm_mul_pd(right[i].f64_x[1], vec);
|
||||
register __m128d c2 = _mm_mul_pd(right[i].f64_x[2], vec);
|
||||
register __m128d c3 = _mm_mul_pd(right[i].f64_x[3], vec);
|
||||
register __m128d c4 = _mm_mul_pd(right[i].f64_x[4], vec);
|
||||
register __m128d c5 = _mm_mul_pd(right[i].f64_x[5], vec);
|
||||
register __m128d c6 = _mm_mul_pd(right[i].f64_x[6], vec);
|
||||
register __m128d c7 = _mm_mul_pd(right[i].f64_x[7], vec);
|
||||
|
||||
ans[i].f64_x[0] = c0;
|
||||
ans[i].f64_x[1] = c1;
|
||||
ans[i].f64_x[2] = c2;
|
||||
ans[i].f64_x[3] = c3;
|
||||
ans[i].f64_x[4] = c4;
|
||||
ans[i].f64_x[5] = c5;
|
||||
ans[i].f64_x[6] = c6;
|
||||
ans[i].f64_x[7] = c7;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(double, avx, ,scalar_mul)
|
||||
{
|
||||
register __m256d vec = _mm256_broadcast_sd(((double *)(scalar->data)));
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m256d c0 = _mm256_mul_pd(right[i].f64_y[0], vec);
|
||||
register __m256d c1 = _mm256_mul_pd(right[i].f64_y[1], vec);
|
||||
register __m256d c2 = _mm256_mul_pd(right[i].f64_y[2], vec);
|
||||
register __m256d c3 = _mm256_mul_pd(right[i].f64_y[3], vec);
|
||||
|
||||
ans[i].f64_y[0] = c0;
|
||||
ans[i].f64_y[1] = c1;
|
||||
ans[i].f64_y[2] = c2;
|
||||
ans[i].f64_y[3] = c3;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(double, 512, ,scalar_mul)
|
||||
{
|
||||
register __m512d vec = _mm512_broadcastsd_pd(_mm_load_pd(scalar));
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
register __m512d c0 = _mm512_mul_pd(right[i].f64_z[0], vec);
|
||||
register __m512d c1 = _mm512_mul_pd(right[i].f64_z[1], vec);
|
||||
|
||||
ans[i].f64_z[0] = c0;
|
||||
ans[i].f64_z[1] = c1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+361
-361
@@ -1,361 +1,361 @@
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrinsic.h"
|
||||
#include "sn_intrincontext.x86.h"
|
||||
|
||||
#define _FMA_SELECT(i) _MM_SHUFFLE(i, i, i, i)
|
||||
|
||||
// float
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, sse, , fma)
|
||||
{
|
||||
const __m128 a0 = _mm_load_ps((float *)&left->f32_x[0]);
|
||||
const __m128 a1 = _mm_load_ps((float *)&left->f32_x[1]);
|
||||
const __m128 a2 = _mm_load_ps((float *)&left->f32_x[2]);
|
||||
const __m128 a3 = _mm_load_ps((float *)&left->f32_x[3]);
|
||||
|
||||
__m128 c0 = _mm_load_ps((float *)&ans->f32_x[0]);
|
||||
__m128 c1 = _mm_load_ps((float *)&ans->f32_x[1]);
|
||||
__m128 c2 = _mm_load_ps((float *)&ans->f32_x[2]);
|
||||
__m128 c3 = _mm_load_ps((float *)&ans->f32_x[3]);
|
||||
|
||||
__m128 bcol;
|
||||
|
||||
/* Column 0 */
|
||||
bcol = _mm_load_ps((float *)&right->f32_x[0]);
|
||||
c0 = _mm_add_ps(c0, _mm_mul_ps(a0, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(0))));
|
||||
c0 = _mm_add_ps(c0, _mm_mul_ps(a1, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(1))));
|
||||
c0 = _mm_add_ps(c0, _mm_mul_ps(a2, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(2))));
|
||||
c0 = _mm_add_ps(c0, _mm_mul_ps(a3, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(3))));
|
||||
|
||||
/* Column 1 */
|
||||
bcol = _mm_load_ps((float *)&right->f32_x[1]);
|
||||
c1 = _mm_add_ps(c1, _mm_mul_ps(a0, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(0))));
|
||||
c1 = _mm_add_ps(c1, _mm_mul_ps(a1, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(1))));
|
||||
c1 = _mm_add_ps(c1, _mm_mul_ps(a2, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(2))));
|
||||
c1 = _mm_add_ps(c1, _mm_mul_ps(a3, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(3))));
|
||||
|
||||
/* Column 2 */
|
||||
bcol = _mm_load_ps((float *)&right->f32_x[2]);
|
||||
c2 = _mm_add_ps(c2, _mm_mul_ps(a0, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(0))));
|
||||
c2 = _mm_add_ps(c2, _mm_mul_ps(a1, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(1))));
|
||||
c2 = _mm_add_ps(c2, _mm_mul_ps(a2, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(2))));
|
||||
c2 = _mm_add_ps(c2, _mm_mul_ps(a3, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(3))));
|
||||
|
||||
/* Column 3 */
|
||||
bcol = _mm_load_ps((float *)&right->f32_x[3]);
|
||||
c3 = _mm_add_ps(c3, _mm_mul_ps(a0, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(0))));
|
||||
c3 = _mm_add_ps(c3, _mm_mul_ps(a1, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(1))));
|
||||
c3 = _mm_add_ps(c3, _mm_mul_ps(a2, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(2))));
|
||||
c3 = _mm_add_ps(c3, _mm_mul_ps(a3, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(3))));
|
||||
|
||||
_mm_store_ps((float *)&ans->f32_x[0], c0);
|
||||
_mm_store_ps((float *)&ans->f32_x[1], c1);
|
||||
_mm_store_ps((float *)&ans->f32_x[2], c2);
|
||||
_mm_store_ps((float *)&ans->f32_x[3], c3);
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, avx, , fma)
|
||||
{
|
||||
static const __m256i b01_shift = { .m256i_i32 = { 0, 1, 2, 3, 5, 6, 7, 4 } };
|
||||
static const __m256i b23_shift = { .m256i_i32 = { 2, 3, 0, 1, 7, 4, 5, 6 } };
|
||||
|
||||
register __m256 a01 = _mm256_load_ps((float *)&left->f32_y[0]);
|
||||
register __m256 a23 = _mm256_load_ps((float *)&left->f32_y[1]);
|
||||
|
||||
register __m256 b01 = _mm256_load_ps((float *)&right->f32_y[0]);
|
||||
register __m256 b23 = _mm256_load_ps((float *)&right->f32_y[1]);
|
||||
b01 = _mm256_permutevar_ps(b01, b01_shift);
|
||||
b23 = _mm256_permutevar_ps(b23, b23_shift);
|
||||
|
||||
register __m256 c01 = _mm256_load_ps((float *)&ans->f32_y[0]);
|
||||
register __m256 c23 = _mm256_load_ps((float *)&ans->f32_y[1]);
|
||||
|
||||
//group 0
|
||||
register __m256 b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(0));
|
||||
register __m256 b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(0));
|
||||
c01 = _mm256_add_ps(_mm256_mul_ps(a01, b01_perm), c01);
|
||||
c23 = _mm256_add_ps(_mm256_mul_ps(a23, b23_perm), c23);
|
||||
|
||||
//group 2
|
||||
b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(2));
|
||||
b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(2));
|
||||
c01 = _mm256_add_ps(_mm256_mul_ps(a23, b01_perm), c01);
|
||||
c23 = _mm256_add_ps(_mm256_mul_ps(a01, b23_perm), c23);
|
||||
|
||||
//group 1
|
||||
register __m256 a12 = _mm256_permute2f128_ps(a01, a23, 0x21);
|
||||
register __m256 a30 = _mm256_permute2f128_ps(a01, a23, 0x30);
|
||||
b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(1));
|
||||
b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(1));
|
||||
c01 = _mm256_add_ps(_mm256_mul_ps(a12, b01_perm), c01);
|
||||
c23 = _mm256_add_ps(_mm256_mul_ps(a30, b23_perm), c23);
|
||||
|
||||
//group 3
|
||||
b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(3));
|
||||
b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(3));
|
||||
c01 = _mm256_add_ps(_mm256_mul_ps(a30, b01_perm), c01);
|
||||
c23 = _mm256_add_ps(_mm256_mul_ps(a12, b23_perm), c23);
|
||||
|
||||
ans->f32_y[0] = c01;
|
||||
ans->f32_y[1] = c23;
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, avx, _fma, fma)
|
||||
{
|
||||
static const __m256i b01_shift = { .m256i_i32 = { 0, 1, 2, 3, 5, 6, 7, 4 } };
|
||||
static const __m256i b23_shift = { .m256i_i32 = { 2, 3, 0, 1, 7, 4, 5, 6 } };
|
||||
|
||||
register __m256 a01 = _mm256_load_ps((float *)&left->f32_y[0]);
|
||||
register __m256 a23 = _mm256_load_ps((float *)&left->f32_y[1]);
|
||||
|
||||
register __m256 b01 = _mm256_load_ps((float *)&right->f32_y[0]);
|
||||
register __m256 b23 = _mm256_load_ps((float *)&right->f32_y[1]);
|
||||
b01 = _mm256_permutevar_ps(b01, b01_shift);
|
||||
b23 = _mm256_permutevar_ps(b23, b23_shift);
|
||||
|
||||
register __m256 c01 = _mm256_load_ps((float *)&ans->f32_y[0]);
|
||||
register __m256 c23 = _mm256_load_ps((float *)&ans->f32_y[1]);
|
||||
|
||||
//group 0
|
||||
register __m256 b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(0));
|
||||
register __m256 b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(0));
|
||||
c01 = _mm256_fmadd_ps(a01, b01_perm, c01);
|
||||
c23 = _mm256_fmadd_ps(a23, b23_perm, c23);
|
||||
|
||||
//group 2
|
||||
b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(2));
|
||||
b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(2));
|
||||
c01 = _mm256_fmadd_ps(a23, b01_perm, c01);
|
||||
c23 = _mm256_fmadd_ps(a01, b23_perm, c23);
|
||||
|
||||
//group 1
|
||||
register __m256 a12 = _mm256_permute2f128_ps(a01, a23, 0x21);
|
||||
register __m256 a30 = _mm256_permute2f128_ps(a01, a23, 0x30);
|
||||
b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(1));
|
||||
b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(1));
|
||||
c01 = _mm256_fmadd_ps(a12, b01_perm, c01);
|
||||
c23 = _mm256_fmadd_ps(a30, b23_perm, c23);
|
||||
|
||||
//group 3
|
||||
b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(3));
|
||||
b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(3));
|
||||
c01 = _mm256_fmadd_ps(a30, b01_perm, c01);
|
||||
c23 = _mm256_fmadd_ps(a12, b23_perm, c23);
|
||||
|
||||
ans->f32_y[0] = c01;
|
||||
ans->f32_y[1] = c23;
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, 512, , fma)
|
||||
{
|
||||
static const __m512i b_shift = { .m512i_i32 = { 0, 1, 2, 3, 5, 6, 7, 4, 10, 11, 8, 9, 15,
|
||||
12, 13, 14 } };
|
||||
|
||||
register __m512 a = _mm512_load_ps((float *)left);
|
||||
register __m512 b = _mm512_load_ps((float *)right);
|
||||
register __m512 c = _mm512_load_ps((float *)ans);
|
||||
|
||||
b = _mm512_permutexvar_ps(b_shift, b);
|
||||
register __m512 a_perm = _mm512_shuffle_f32x4(a, a, _MM_SHUFFLE(3, 2, 1, 0));
|
||||
register __m512 b_perm = _mm512_permute_ps(b, _FMA_SELECT(0));
|
||||
c = _mm512_fmadd_ps(a_perm, b_perm, c);
|
||||
|
||||
a_perm = _mm512_shuffle_f32x4(a, a, _MM_SHUFFLE(2, 1, 0, 3));
|
||||
b_perm = _mm512_permute_ps(b, _FMA_SELECT(1));
|
||||
c = _mm512_fmadd_ps(a_perm, b_perm, c);
|
||||
|
||||
a_perm = _mm512_shuffle_f32x4(a, a, _MM_SHUFFLE(1, 0, 3, 2));
|
||||
b_perm = _mm512_permute_ps(b, _FMA_SELECT(2));
|
||||
c = _mm512_fmadd_ps(a_perm, b_perm, c);
|
||||
|
||||
a_perm = _mm512_shuffle_f32x4(a, a, _MM_SHUFFLE(0, 3, 2, 1));
|
||||
b_perm = _mm512_permute_ps(b, _FMA_SELECT(3));
|
||||
c = _mm512_fmadd_ps(a_perm, b_perm, c);
|
||||
|
||||
_mm512_store_ps((float *)ans, c);
|
||||
}
|
||||
|
||||
// double
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, sse, , fma)
|
||||
{
|
||||
for (int col = 0; col < 4; ++col) {
|
||||
/* current answer column (two chunks: rows 0-1 and 2-3) */
|
||||
register __m128d c_lo = _mm_load_pd(ans->f64_x + (col * 2 + 0));
|
||||
register __m128d c_hi = _mm_load_pd(ans->f64_x + (col * 2 + 1));
|
||||
|
||||
/* right matrix column split into two chunks */
|
||||
register __m128d b_lo = _mm_load_pd(right + (2 * col + 0));
|
||||
register __m128d b_hi = _mm_load_pd(right + (2 * col + 1));
|
||||
|
||||
/* k = 0 */
|
||||
register __m128d a_lo = _mm_load_pd(left + (0 * 2 + 0));
|
||||
register __m128d a_hi = _mm_load_pd(left + (0 * 2 + 1));
|
||||
register __m128d b = _mm_shuffle_pd(b_lo, b_lo, 0x0);
|
||||
c_lo = _mm_add_pd(c_lo, _mm_mul_pd(a_lo, b));
|
||||
c_hi = _mm_add_pd(c_hi, _mm_mul_pd(a_hi, b));
|
||||
|
||||
/* k = 1 */
|
||||
a_lo = _mm_load_pd(left + (1 * 2 + 0));
|
||||
a_hi = _mm_load_pd(left + (1 * 2 + 1));
|
||||
b = _mm_shuffle_pd(b_lo, b_lo, 0x3);
|
||||
c_lo = _mm_add_pd(c_lo, _mm_mul_pd(a_lo, b));
|
||||
c_hi = _mm_add_pd(c_hi, _mm_mul_pd(a_hi, b));
|
||||
|
||||
/* k = 2 */
|
||||
a_lo = _mm_load_pd(left + (1 * 2 + 0));
|
||||
a_hi = _mm_load_pd(left + (1 * 2 + 1));
|
||||
b = _mm_shuffle_pd(b_hi, b_hi, 0x0);
|
||||
c_lo = _mm_add_pd(c_lo, _mm_mul_pd(a_lo, b));
|
||||
c_hi = _mm_add_pd(c_hi, _mm_mul_pd(a_hi, b));
|
||||
|
||||
/* k = 3 */
|
||||
a_lo = _mm_load_pd(left + (1 * 2 + 0));
|
||||
a_hi = _mm_load_pd(left + (1 * 2 + 1));
|
||||
b = _mm_shuffle_pd(b_hi, b_hi, 0x3);
|
||||
c_lo = _mm_add_pd(c_lo, _mm_mul_pd(a_lo, b));
|
||||
c_hi = _mm_add_pd(c_hi, _mm_mul_pd(a_hi, b));
|
||||
|
||||
ans->f64_x[col * 2 + 0] = c_lo;
|
||||
ans->f64_x[col * 2 + 1] = c_hi;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, avx, , fma)
|
||||
{
|
||||
const __m256d a0 = _mm256_load_pd((double *)&left->f64_y[0]);
|
||||
const __m256d a1 = _mm256_load_pd((double *)&left->f64_y[1]);
|
||||
const __m256d a2 = _mm256_load_pd((double *)&left->f64_y[2]);
|
||||
const __m256d a3 = _mm256_load_pd((double *)&left->f64_y[3]);
|
||||
|
||||
__m256d b0 = _mm256_load_pd((double *)&right->f64_y[0]);
|
||||
__m256d b1 = _mm256_load_pd((double *)&right->f64_y[1]);
|
||||
__m256d b2 = _mm256_load_pd((double *)&right->f64_y[2]);
|
||||
__m256d b3 = _mm256_load_pd((double *)&right->f64_y[3]);
|
||||
|
||||
register __m256d ccol;
|
||||
|
||||
/* Column 0 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[0]);
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a0, _mm256_permute4x64_pd(b0, _FMA_SELECT(0))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a1, _mm256_permute4x64_pd(b0, _FMA_SELECT(1))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a2, _mm256_permute4x64_pd(b0, _FMA_SELECT(2))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a3, _mm256_permute4x64_pd(b0, _FMA_SELECT(3))));
|
||||
ans->f64_y[0] = ccol;
|
||||
/* Column 1 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[1]);
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a0, _mm256_permute4x64_pd(b1, _FMA_SELECT(0))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a1, _mm256_permute4x64_pd(b1, _FMA_SELECT(1))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a2, _mm256_permute4x64_pd(b1, _FMA_SELECT(2))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a3, _mm256_permute4x64_pd(b1, _FMA_SELECT(3))));
|
||||
ans->f64_y[1] = ccol;
|
||||
/* Column 2 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[2]);
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a0, _mm256_permute4x64_pd(b2, _FMA_SELECT(0))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a1, _mm256_permute4x64_pd(b2, _FMA_SELECT(1))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a2, _mm256_permute4x64_pd(b2, _FMA_SELECT(2))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a3, _mm256_permute4x64_pd(b2, _FMA_SELECT(3))));
|
||||
ans->f64_y[2] = ccol;
|
||||
/* Column 3 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[3]);
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a0, _mm256_permute4x64_pd(b3, _FMA_SELECT(0))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a1, _mm256_permute4x64_pd(b3, _FMA_SELECT(1))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a2, _mm256_permute4x64_pd(b3, _FMA_SELECT(2))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a3, _mm256_permute4x64_pd(b3, _FMA_SELECT(3))));
|
||||
ans->f64_y[3] = ccol;
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, avx, _fma, fma)
|
||||
{
|
||||
const __m256d a0 = _mm256_load_pd((double *)&left->f64_y[0]);
|
||||
const __m256d a1 = _mm256_load_pd((double *)&left->f64_y[1]);
|
||||
const __m256d a2 = _mm256_load_pd((double *)&left->f64_y[2]);
|
||||
const __m256d a3 = _mm256_load_pd((double *)&left->f64_y[3]);
|
||||
|
||||
__m256d b0 = _mm256_load_pd((double *)&right->f64_y[0]);
|
||||
__m256d b1 = _mm256_load_pd((double *)&right->f64_y[1]);
|
||||
__m256d b2 = _mm256_load_pd((double *)&right->f64_y[2]);
|
||||
__m256d b3 = _mm256_load_pd((double *)&right->f64_y[3]);
|
||||
|
||||
register __m256d ccol;
|
||||
|
||||
/* Column 0 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[0]);
|
||||
ccol = _mm256_fmadd_pd(a0, _mm256_permute4x64_pd(b0, _FMA_SELECT(0)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a1, _mm256_permute4x64_pd(b0, _FMA_SELECT(1)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a2, _mm256_permute4x64_pd(b0, _FMA_SELECT(2)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a3, _mm256_permute4x64_pd(b0, _FMA_SELECT(3)), ccol);
|
||||
ans->f64_y[0] = ccol;
|
||||
/* Column 1 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[1]);
|
||||
ccol = _mm256_fmadd_pd(a0, _mm256_permute4x64_pd(b1, _FMA_SELECT(0)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a1, _mm256_permute4x64_pd(b1, _FMA_SELECT(1)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a2, _mm256_permute4x64_pd(b1, _FMA_SELECT(2)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a3, _mm256_permute4x64_pd(b1, _FMA_SELECT(3)), ccol);
|
||||
ans->f64_y[1] = ccol;
|
||||
/* Column 2 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[2]);
|
||||
ccol = _mm256_fmadd_pd(a0, _mm256_permute4x64_pd(b2, _FMA_SELECT(0)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a1, _mm256_permute4x64_pd(b2, _FMA_SELECT(1)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a2, _mm256_permute4x64_pd(b2, _FMA_SELECT(2)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a3, _mm256_permute4x64_pd(b2, _FMA_SELECT(3)), ccol);
|
||||
ans->f64_y[2] = ccol;
|
||||
/* Column 3 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[3]);
|
||||
ccol = _mm256_fmadd_pd(a0, _mm256_permute4x64_pd(b3, _FMA_SELECT(0)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a1, _mm256_permute4x64_pd(b3, _FMA_SELECT(1)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a2, _mm256_permute4x64_pd(b3, _FMA_SELECT(2)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a3, _mm256_permute4x64_pd(b3, _FMA_SELECT(3)), ccol);
|
||||
ans->f64_y[3] = ccol;
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, 512, , fma)
|
||||
{
|
||||
static const __m512i b01_shift = { .m512i_i64 = { 0, 1, 2, 3, 5, 6, 7, 4 } };
|
||||
static const __m512i b23_shift = { .m512i_i64 = { 2, 3, 0, 1, 7, 4, 5, 6 } };
|
||||
|
||||
register __m512d a01 = _mm512_load_pd((double *)&left->f64_z[0]);
|
||||
register __m512d a23 = _mm512_load_pd((double *)&left->f64_z[1]);
|
||||
|
||||
register __m512d b01 = _mm512_load_pd((double *)&right->f64_z[0]);
|
||||
register __m512d b23 = _mm512_load_pd((double *)&right->f64_z[1]);
|
||||
b01 = _mm512_permutexvar_pd(b01_shift, b01);
|
||||
b23 = _mm512_permutexvar_pd(b23_shift, b23);
|
||||
|
||||
register __m512d c01 = _mm512_load_pd((float *)&ans->f64_z[0]);
|
||||
register __m512d c23 = _mm512_load_pd((float *)&ans->f64_z[1]);
|
||||
|
||||
//group 0
|
||||
register __m512d b01_perm = _mm512_shuffle_pd(b01, b01, _FMA_SELECT(0));
|
||||
register __m512d b23_perm = _mm512_shuffle_pd(b23, b23, _FMA_SELECT(0));
|
||||
c01 = _mm512_fmadd_pd(a01, b01_perm, c01);
|
||||
c23 = _mm512_fmadd_pd(a23, b23_perm, c23);
|
||||
|
||||
//group 2
|
||||
b01_perm = _mm512_shuffle_pd(b01, b01, _FMA_SELECT(2));
|
||||
b23_perm = _mm512_shuffle_pd(b23, b23, _FMA_SELECT(2));
|
||||
c01 = _mm512_fmadd_pd(a23, b01_perm, c01);
|
||||
c23 = _mm512_fmadd_pd(a01, b23_perm, c23);
|
||||
|
||||
//group 1
|
||||
register __m512d a12 = _mm512_shuffle_f64x2(a01, a23, _MM_SHUFFLE(1, 0, 3, 2));
|
||||
register __m512d a30 = _mm512_shuffle_f64x2(a23, a01, _MM_SHUFFLE(1, 0, 3, 2));
|
||||
b01_perm = _mm512_shuffle_pd(b01, b01, _FMA_SELECT(1));
|
||||
b23_perm = _mm512_shuffle_pd(b23, b23, _FMA_SELECT(1));
|
||||
c01 = _mm512_fmadd_pd(a12, b01_perm, c01);
|
||||
c23 = _mm512_fmadd_pd(a30, b23_perm, c23);
|
||||
|
||||
//group 3
|
||||
b01_perm = _mm512_shuffle_pd(b01, b01, _FMA_SELECT(3));
|
||||
b23_perm = _mm512_shuffle_pd(b23, b23, _FMA_SELECT(3));
|
||||
c01 = _mm512_fmadd_pd(a30, b01_perm, c01);
|
||||
c23 = _mm512_fmadd_pd(a12, b23_perm, c23);
|
||||
|
||||
ans->f64_z[0] = c01;
|
||||
ans->f64_z[1] = c23;
|
||||
}
|
||||
|
||||
#endif
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrinsic.h"
|
||||
#include "sn_intrincontext.x86.h"
|
||||
|
||||
#define _FMA_SELECT(i) _MM_SHUFFLE(i, i, i, i)
|
||||
|
||||
// float
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, sse, , fma)
|
||||
{
|
||||
const __m128 a0 = _mm_load_ps((float *)&left->f32_x[0]);
|
||||
const __m128 a1 = _mm_load_ps((float *)&left->f32_x[1]);
|
||||
const __m128 a2 = _mm_load_ps((float *)&left->f32_x[2]);
|
||||
const __m128 a3 = _mm_load_ps((float *)&left->f32_x[3]);
|
||||
|
||||
__m128 c0 = _mm_load_ps((float *)&ans->f32_x[0]);
|
||||
__m128 c1 = _mm_load_ps((float *)&ans->f32_x[1]);
|
||||
__m128 c2 = _mm_load_ps((float *)&ans->f32_x[2]);
|
||||
__m128 c3 = _mm_load_ps((float *)&ans->f32_x[3]);
|
||||
|
||||
__m128 bcol;
|
||||
|
||||
/* Column 0 */
|
||||
bcol = _mm_load_ps((float *)&right->f32_x[0]);
|
||||
c0 = _mm_add_ps(c0, _mm_mul_ps(a0, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(0))));
|
||||
c0 = _mm_add_ps(c0, _mm_mul_ps(a1, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(1))));
|
||||
c0 = _mm_add_ps(c0, _mm_mul_ps(a2, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(2))));
|
||||
c0 = _mm_add_ps(c0, _mm_mul_ps(a3, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(3))));
|
||||
|
||||
/* Column 1 */
|
||||
bcol = _mm_load_ps((float *)&right->f32_x[1]);
|
||||
c1 = _mm_add_ps(c1, _mm_mul_ps(a0, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(0))));
|
||||
c1 = _mm_add_ps(c1, _mm_mul_ps(a1, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(1))));
|
||||
c1 = _mm_add_ps(c1, _mm_mul_ps(a2, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(2))));
|
||||
c1 = _mm_add_ps(c1, _mm_mul_ps(a3, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(3))));
|
||||
|
||||
/* Column 2 */
|
||||
bcol = _mm_load_ps((float *)&right->f32_x[2]);
|
||||
c2 = _mm_add_ps(c2, _mm_mul_ps(a0, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(0))));
|
||||
c2 = _mm_add_ps(c2, _mm_mul_ps(a1, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(1))));
|
||||
c2 = _mm_add_ps(c2, _mm_mul_ps(a2, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(2))));
|
||||
c2 = _mm_add_ps(c2, _mm_mul_ps(a3, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(3))));
|
||||
|
||||
/* Column 3 */
|
||||
bcol = _mm_load_ps((float *)&right->f32_x[3]);
|
||||
c3 = _mm_add_ps(c3, _mm_mul_ps(a0, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(0))));
|
||||
c3 = _mm_add_ps(c3, _mm_mul_ps(a1, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(1))));
|
||||
c3 = _mm_add_ps(c3, _mm_mul_ps(a2, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(2))));
|
||||
c3 = _mm_add_ps(c3, _mm_mul_ps(a3, _mm_shuffle_ps(bcol, bcol, _FMA_SELECT(3))));
|
||||
|
||||
_mm_store_ps((float *)&ans->f32_x[0], c0);
|
||||
_mm_store_ps((float *)&ans->f32_x[1], c1);
|
||||
_mm_store_ps((float *)&ans->f32_x[2], c2);
|
||||
_mm_store_ps((float *)&ans->f32_x[3], c3);
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, avx, , fma)
|
||||
{
|
||||
static const __m256i b01_shift = { .m256i_i32 = { 0, 1, 2, 3, 5, 6, 7, 4 } };
|
||||
static const __m256i b23_shift = { .m256i_i32 = { 2, 3, 0, 1, 7, 4, 5, 6 } };
|
||||
|
||||
register __m256 a01 = _mm256_load_ps((float *)&left->f32_y[0]);
|
||||
register __m256 a23 = _mm256_load_ps((float *)&left->f32_y[1]);
|
||||
|
||||
register __m256 b01 = _mm256_load_ps((float *)&right->f32_y[0]);
|
||||
register __m256 b23 = _mm256_load_ps((float *)&right->f32_y[1]);
|
||||
b01 = _mm256_permutevar_ps(b01, b01_shift);
|
||||
b23 = _mm256_permutevar_ps(b23, b23_shift);
|
||||
|
||||
register __m256 c01 = _mm256_load_ps((float *)&ans->f32_y[0]);
|
||||
register __m256 c23 = _mm256_load_ps((float *)&ans->f32_y[1]);
|
||||
|
||||
//group 0
|
||||
register __m256 b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(0));
|
||||
register __m256 b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(0));
|
||||
c01 = _mm256_add_ps(_mm256_mul_ps(a01, b01_perm), c01);
|
||||
c23 = _mm256_add_ps(_mm256_mul_ps(a23, b23_perm), c23);
|
||||
|
||||
//group 2
|
||||
b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(2));
|
||||
b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(2));
|
||||
c01 = _mm256_add_ps(_mm256_mul_ps(a23, b01_perm), c01);
|
||||
c23 = _mm256_add_ps(_mm256_mul_ps(a01, b23_perm), c23);
|
||||
|
||||
//group 1
|
||||
register __m256 a12 = _mm256_permute2f128_ps(a01, a23, 0x21);
|
||||
register __m256 a30 = _mm256_permute2f128_ps(a01, a23, 0x30);
|
||||
b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(1));
|
||||
b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(1));
|
||||
c01 = _mm256_add_ps(_mm256_mul_ps(a12, b01_perm), c01);
|
||||
c23 = _mm256_add_ps(_mm256_mul_ps(a30, b23_perm), c23);
|
||||
|
||||
//group 3
|
||||
b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(3));
|
||||
b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(3));
|
||||
c01 = _mm256_add_ps(_mm256_mul_ps(a30, b01_perm), c01);
|
||||
c23 = _mm256_add_ps(_mm256_mul_ps(a12, b23_perm), c23);
|
||||
|
||||
ans->f32_y[0] = c01;
|
||||
ans->f32_y[1] = c23;
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, avx, _fma, fma)
|
||||
{
|
||||
static const __m256i b01_shift = { .m256i_i32 = { 0, 1, 2, 3, 5, 6, 7, 4 } };
|
||||
static const __m256i b23_shift = { .m256i_i32 = { 2, 3, 0, 1, 7, 4, 5, 6 } };
|
||||
|
||||
register __m256 a01 = _mm256_load_ps((float *)&left->f32_y[0]);
|
||||
register __m256 a23 = _mm256_load_ps((float *)&left->f32_y[1]);
|
||||
|
||||
register __m256 b01 = _mm256_load_ps((float *)&right->f32_y[0]);
|
||||
register __m256 b23 = _mm256_load_ps((float *)&right->f32_y[1]);
|
||||
b01 = _mm256_permutevar_ps(b01, b01_shift);
|
||||
b23 = _mm256_permutevar_ps(b23, b23_shift);
|
||||
|
||||
register __m256 c01 = _mm256_load_ps((float *)&ans->f32_y[0]);
|
||||
register __m256 c23 = _mm256_load_ps((float *)&ans->f32_y[1]);
|
||||
|
||||
//group 0
|
||||
register __m256 b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(0));
|
||||
register __m256 b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(0));
|
||||
c01 = _mm256_fmadd_ps(a01, b01_perm, c01);
|
||||
c23 = _mm256_fmadd_ps(a23, b23_perm, c23);
|
||||
|
||||
//group 2
|
||||
b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(2));
|
||||
b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(2));
|
||||
c01 = _mm256_fmadd_ps(a23, b01_perm, c01);
|
||||
c23 = _mm256_fmadd_ps(a01, b23_perm, c23);
|
||||
|
||||
//group 1
|
||||
register __m256 a12 = _mm256_permute2f128_ps(a01, a23, 0x21);
|
||||
register __m256 a30 = _mm256_permute2f128_ps(a01, a23, 0x30);
|
||||
b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(1));
|
||||
b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(1));
|
||||
c01 = _mm256_fmadd_ps(a12, b01_perm, c01);
|
||||
c23 = _mm256_fmadd_ps(a30, b23_perm, c23);
|
||||
|
||||
//group 3
|
||||
b01_perm = _mm256_shuffle_ps(b01, b01, _FMA_SELECT(3));
|
||||
b23_perm = _mm256_shuffle_ps(b23, b23, _FMA_SELECT(3));
|
||||
c01 = _mm256_fmadd_ps(a30, b01_perm, c01);
|
||||
c23 = _mm256_fmadd_ps(a12, b23_perm, c23);
|
||||
|
||||
ans->f32_y[0] = c01;
|
||||
ans->f32_y[1] = c23;
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(float, 512, , fma)
|
||||
{
|
||||
static const __m512i b_shift = { .m512i_i32 = { 0, 1, 2, 3, 5, 6, 7, 4, 10, 11, 8, 9, 15,
|
||||
12, 13, 14 } };
|
||||
|
||||
register __m512 a = _mm512_load_ps((float *)left);
|
||||
register __m512 b = _mm512_load_ps((float *)right);
|
||||
register __m512 c = _mm512_load_ps((float *)ans);
|
||||
|
||||
b = _mm512_permutexvar_ps(b_shift, b);
|
||||
register __m512 a_perm = _mm512_shuffle_f32x4(a, a, _MM_SHUFFLE(3, 2, 1, 0));
|
||||
register __m512 b_perm = _mm512_permute_ps(b, _FMA_SELECT(0));
|
||||
c = _mm512_fmadd_ps(a_perm, b_perm, c);
|
||||
|
||||
a_perm = _mm512_shuffle_f32x4(a, a, _MM_SHUFFLE(2, 1, 0, 3));
|
||||
b_perm = _mm512_permute_ps(b, _FMA_SELECT(1));
|
||||
c = _mm512_fmadd_ps(a_perm, b_perm, c);
|
||||
|
||||
a_perm = _mm512_shuffle_f32x4(a, a, _MM_SHUFFLE(1, 0, 3, 2));
|
||||
b_perm = _mm512_permute_ps(b, _FMA_SELECT(2));
|
||||
c = _mm512_fmadd_ps(a_perm, b_perm, c);
|
||||
|
||||
a_perm = _mm512_shuffle_f32x4(a, a, _MM_SHUFFLE(0, 3, 2, 1));
|
||||
b_perm = _mm512_permute_ps(b, _FMA_SELECT(3));
|
||||
c = _mm512_fmadd_ps(a_perm, b_perm, c);
|
||||
|
||||
_mm512_store_ps((float *)ans, c);
|
||||
}
|
||||
|
||||
// double
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, sse, , fma)
|
||||
{
|
||||
for (int col = 0; col < 4; ++col) {
|
||||
/* current answer column (two chunks: rows 0-1 and 2-3) */
|
||||
register __m128d c_lo = _mm_load_pd(ans->f64_x + (col * 2 + 0));
|
||||
register __m128d c_hi = _mm_load_pd(ans->f64_x + (col * 2 + 1));
|
||||
|
||||
/* right matrix column split into two chunks */
|
||||
register __m128d b_lo = _mm_load_pd(right + (2 * col + 0));
|
||||
register __m128d b_hi = _mm_load_pd(right + (2 * col + 1));
|
||||
|
||||
/* k = 0 */
|
||||
register __m128d a_lo = _mm_load_pd(left + (0 * 2 + 0));
|
||||
register __m128d a_hi = _mm_load_pd(left + (0 * 2 + 1));
|
||||
register __m128d b = _mm_shuffle_pd(b_lo, b_lo, 0x0);
|
||||
c_lo = _mm_add_pd(c_lo, _mm_mul_pd(a_lo, b));
|
||||
c_hi = _mm_add_pd(c_hi, _mm_mul_pd(a_hi, b));
|
||||
|
||||
/* k = 1 */
|
||||
a_lo = _mm_load_pd(left + (1 * 2 + 0));
|
||||
a_hi = _mm_load_pd(left + (1 * 2 + 1));
|
||||
b = _mm_shuffle_pd(b_lo, b_lo, 0x3);
|
||||
c_lo = _mm_add_pd(c_lo, _mm_mul_pd(a_lo, b));
|
||||
c_hi = _mm_add_pd(c_hi, _mm_mul_pd(a_hi, b));
|
||||
|
||||
/* k = 2 */
|
||||
a_lo = _mm_load_pd(left + (1 * 2 + 0));
|
||||
a_hi = _mm_load_pd(left + (1 * 2 + 1));
|
||||
b = _mm_shuffle_pd(b_hi, b_hi, 0x0);
|
||||
c_lo = _mm_add_pd(c_lo, _mm_mul_pd(a_lo, b));
|
||||
c_hi = _mm_add_pd(c_hi, _mm_mul_pd(a_hi, b));
|
||||
|
||||
/* k = 3 */
|
||||
a_lo = _mm_load_pd(left + (1 * 2 + 0));
|
||||
a_hi = _mm_load_pd(left + (1 * 2 + 1));
|
||||
b = _mm_shuffle_pd(b_hi, b_hi, 0x3);
|
||||
c_lo = _mm_add_pd(c_lo, _mm_mul_pd(a_lo, b));
|
||||
c_hi = _mm_add_pd(c_hi, _mm_mul_pd(a_hi, b));
|
||||
|
||||
ans->f64_x[col * 2 + 0] = c_lo;
|
||||
ans->f64_x[col * 2 + 1] = c_hi;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, avx, , fma)
|
||||
{
|
||||
const __m256d a0 = _mm256_load_pd((double *)&left->f64_y[0]);
|
||||
const __m256d a1 = _mm256_load_pd((double *)&left->f64_y[1]);
|
||||
const __m256d a2 = _mm256_load_pd((double *)&left->f64_y[2]);
|
||||
const __m256d a3 = _mm256_load_pd((double *)&left->f64_y[3]);
|
||||
|
||||
__m256d b0 = _mm256_load_pd((double *)&right->f64_y[0]);
|
||||
__m256d b1 = _mm256_load_pd((double *)&right->f64_y[1]);
|
||||
__m256d b2 = _mm256_load_pd((double *)&right->f64_y[2]);
|
||||
__m256d b3 = _mm256_load_pd((double *)&right->f64_y[3]);
|
||||
|
||||
register __m256d ccol;
|
||||
|
||||
/* Column 0 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[0]);
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a0, _mm256_permute4x64_pd(b0, _FMA_SELECT(0))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a1, _mm256_permute4x64_pd(b0, _FMA_SELECT(1))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a2, _mm256_permute4x64_pd(b0, _FMA_SELECT(2))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a3, _mm256_permute4x64_pd(b0, _FMA_SELECT(3))));
|
||||
ans->f64_y[0] = ccol;
|
||||
/* Column 1 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[1]);
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a0, _mm256_permute4x64_pd(b1, _FMA_SELECT(0))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a1, _mm256_permute4x64_pd(b1, _FMA_SELECT(1))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a2, _mm256_permute4x64_pd(b1, _FMA_SELECT(2))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a3, _mm256_permute4x64_pd(b1, _FMA_SELECT(3))));
|
||||
ans->f64_y[1] = ccol;
|
||||
/* Column 2 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[2]);
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a0, _mm256_permute4x64_pd(b2, _FMA_SELECT(0))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a1, _mm256_permute4x64_pd(b2, _FMA_SELECT(1))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a2, _mm256_permute4x64_pd(b2, _FMA_SELECT(2))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a3, _mm256_permute4x64_pd(b2, _FMA_SELECT(3))));
|
||||
ans->f64_y[2] = ccol;
|
||||
/* Column 3 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[3]);
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a0, _mm256_permute4x64_pd(b3, _FMA_SELECT(0))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a1, _mm256_permute4x64_pd(b3, _FMA_SELECT(1))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a2, _mm256_permute4x64_pd(b3, _FMA_SELECT(2))));
|
||||
ccol = _mm256_add_pd(ccol, _mm256_mul_pd(a3, _mm256_permute4x64_pd(b3, _FMA_SELECT(3))));
|
||||
ans->f64_y[3] = ccol;
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, avx, _fma, fma)
|
||||
{
|
||||
const __m256d a0 = _mm256_load_pd((double *)&left->f64_y[0]);
|
||||
const __m256d a1 = _mm256_load_pd((double *)&left->f64_y[1]);
|
||||
const __m256d a2 = _mm256_load_pd((double *)&left->f64_y[2]);
|
||||
const __m256d a3 = _mm256_load_pd((double *)&left->f64_y[3]);
|
||||
|
||||
__m256d b0 = _mm256_load_pd((double *)&right->f64_y[0]);
|
||||
__m256d b1 = _mm256_load_pd((double *)&right->f64_y[1]);
|
||||
__m256d b2 = _mm256_load_pd((double *)&right->f64_y[2]);
|
||||
__m256d b3 = _mm256_load_pd((double *)&right->f64_y[3]);
|
||||
|
||||
register __m256d ccol;
|
||||
|
||||
/* Column 0 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[0]);
|
||||
ccol = _mm256_fmadd_pd(a0, _mm256_permute4x64_pd(b0, _FMA_SELECT(0)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a1, _mm256_permute4x64_pd(b0, _FMA_SELECT(1)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a2, _mm256_permute4x64_pd(b0, _FMA_SELECT(2)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a3, _mm256_permute4x64_pd(b0, _FMA_SELECT(3)), ccol);
|
||||
ans->f64_y[0] = ccol;
|
||||
/* Column 1 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[1]);
|
||||
ccol = _mm256_fmadd_pd(a0, _mm256_permute4x64_pd(b1, _FMA_SELECT(0)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a1, _mm256_permute4x64_pd(b1, _FMA_SELECT(1)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a2, _mm256_permute4x64_pd(b1, _FMA_SELECT(2)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a3, _mm256_permute4x64_pd(b1, _FMA_SELECT(3)), ccol);
|
||||
ans->f64_y[1] = ccol;
|
||||
/* Column 2 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[2]);
|
||||
ccol = _mm256_fmadd_pd(a0, _mm256_permute4x64_pd(b2, _FMA_SELECT(0)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a1, _mm256_permute4x64_pd(b2, _FMA_SELECT(1)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a2, _mm256_permute4x64_pd(b2, _FMA_SELECT(2)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a3, _mm256_permute4x64_pd(b2, _FMA_SELECT(3)), ccol);
|
||||
ans->f64_y[2] = ccol;
|
||||
/* Column 3 */
|
||||
ccol = _mm256_load_pd((double *)&ans->f32_y[3]);
|
||||
ccol = _mm256_fmadd_pd(a0, _mm256_permute4x64_pd(b3, _FMA_SELECT(0)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a1, _mm256_permute4x64_pd(b3, _FMA_SELECT(1)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a2, _mm256_permute4x64_pd(b3, _FMA_SELECT(2)), ccol);
|
||||
ccol = _mm256_fmadd_pd(a3, _mm256_permute4x64_pd(b3, _FMA_SELECT(3)), ccol);
|
||||
ans->f64_y[3] = ccol;
|
||||
}
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS(double, 512, , fma)
|
||||
{
|
||||
static const __m512i b01_shift = { .m512i_i64 = { 0, 1, 2, 3, 5, 6, 7, 4 } };
|
||||
static const __m512i b23_shift = { .m512i_i64 = { 2, 3, 0, 1, 7, 4, 5, 6 } };
|
||||
|
||||
register __m512d a01 = _mm512_load_pd((double *)&left->f64_z[0]);
|
||||
register __m512d a23 = _mm512_load_pd((double *)&left->f64_z[1]);
|
||||
|
||||
register __m512d b01 = _mm512_load_pd((double *)&right->f64_z[0]);
|
||||
register __m512d b23 = _mm512_load_pd((double *)&right->f64_z[1]);
|
||||
b01 = _mm512_permutexvar_pd(b01_shift, b01);
|
||||
b23 = _mm512_permutexvar_pd(b23_shift, b23);
|
||||
|
||||
register __m512d c01 = _mm512_load_pd((float *)&ans->f64_z[0]);
|
||||
register __m512d c23 = _mm512_load_pd((float *)&ans->f64_z[1]);
|
||||
|
||||
//group 0
|
||||
register __m512d b01_perm = _mm512_shuffle_pd(b01, b01, _FMA_SELECT(0));
|
||||
register __m512d b23_perm = _mm512_shuffle_pd(b23, b23, _FMA_SELECT(0));
|
||||
c01 = _mm512_fmadd_pd(a01, b01_perm, c01);
|
||||
c23 = _mm512_fmadd_pd(a23, b23_perm, c23);
|
||||
|
||||
//group 2
|
||||
b01_perm = _mm512_shuffle_pd(b01, b01, _FMA_SELECT(2));
|
||||
b23_perm = _mm512_shuffle_pd(b23, b23, _FMA_SELECT(2));
|
||||
c01 = _mm512_fmadd_pd(a23, b01_perm, c01);
|
||||
c23 = _mm512_fmadd_pd(a01, b23_perm, c23);
|
||||
|
||||
//group 1
|
||||
register __m512d a12 = _mm512_shuffle_f64x2(a01, a23, _MM_SHUFFLE(1, 0, 3, 2));
|
||||
register __m512d a30 = _mm512_shuffle_f64x2(a23, a01, _MM_SHUFFLE(1, 0, 3, 2));
|
||||
b01_perm = _mm512_shuffle_pd(b01, b01, _FMA_SELECT(1));
|
||||
b23_perm = _mm512_shuffle_pd(b23, b23, _FMA_SELECT(1));
|
||||
c01 = _mm512_fmadd_pd(a12, b01_perm, c01);
|
||||
c23 = _mm512_fmadd_pd(a30, b23_perm, c23);
|
||||
|
||||
//group 3
|
||||
b01_perm = _mm512_shuffle_pd(b01, b01, _FMA_SELECT(3));
|
||||
b23_perm = _mm512_shuffle_pd(b23, b23, _FMA_SELECT(3));
|
||||
c01 = _mm512_fmadd_pd(a30, b01_perm, c01);
|
||||
c23 = _mm512_fmadd_pd(a12, b23_perm, c23);
|
||||
|
||||
ans->f64_z[0] = c01;
|
||||
ans->f64_z[1] = c23;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,301 +1,301 @@
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_matkernel.h"
|
||||
|
||||
DECLARE_BUILD_PANEL(avx, float)
|
||||
{
|
||||
const int Q = 8; /* fixed for AVX float panel */
|
||||
|
||||
/* Neighbor kernels; substitute global zero kernel where out-of-bounds */
|
||||
const int has_right = (col_index + 1) < col_length;
|
||||
const int has_bottom = (row_index + 1) < row_length;
|
||||
|
||||
const MAT_KERNEL(float) *const k_lt = matrix + (row_index * col_length + col_index);
|
||||
const MAT_KERNEL(float) *const k_rt =
|
||||
has_right ? (matrix + (row_index * col_length + (col_index + 1))) :
|
||||
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
|
||||
const MAT_KERNEL(float) *const k_lb =
|
||||
has_bottom ? (matrix + ((row_index + 1) * col_length + col_index)) :
|
||||
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
|
||||
const MAT_KERNEL(float) *const k_rb =
|
||||
(has_right && has_bottom) ?
|
||||
(matrix + ((row_index + 1) * col_length + (col_index + 1))) :
|
||||
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
|
||||
|
||||
register __m128 top128, bot128;
|
||||
register __m256 col256;
|
||||
|
||||
for (int pc = 0; pc < Q; ++pc) {
|
||||
const int is_right_half = (pc >= 4);
|
||||
const int kc_col = pc & 3; /* column index inside 4x4 kernel */
|
||||
|
||||
const MAT_KERNEL(float) *src_top = is_right_half ? k_rt : k_lt;
|
||||
const MAT_KERNEL(float) *src_bot = is_right_half ? k_rb : k_lb;
|
||||
|
||||
/* Vector loads: each kernel column is a compact __m128 */
|
||||
top128 = src_top->f32_x[kc_col];
|
||||
bot128 = src_bot->f32_x[kc_col];
|
||||
|
||||
/* Combine into an AVX column: low 128 = top, high 128 = bottom */
|
||||
col256 = _mm256_set_m128(bot128, top128);
|
||||
|
||||
PANEL_COL_VEC((*panel), pc, 0) = col256;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUILD_PANEL(512, float)
|
||||
{
|
||||
const MAT_KERNEL(float) *const zero = (const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
|
||||
const MAT_KERNEL(float) * k[4][4];
|
||||
|
||||
for (int kc = 0; kc < 4; ++kc) {
|
||||
for (int kr = 0; kr < 4; ++kr) {
|
||||
const int col = col_index + kc;
|
||||
const int row = row_index + kr;
|
||||
k[kc][kr] = (col < col_length && row < row_length) ?
|
||||
(matrix + (row * col_length + col)) :
|
||||
zero;
|
||||
}
|
||||
}
|
||||
|
||||
/* Each panel column corresponds to a kernel column (0..3) within a block col (0..3). */
|
||||
for (int pc = 0; pc < 16; ++pc) {
|
||||
const int blk_col = pc >> 2; /* which kernel column block (0..3) */
|
||||
const int kc_col = pc & 3; /* column inside a 4x4 kernel */
|
||||
|
||||
const __m128 r0 = k[blk_col][0]->f32_x[kc_col];
|
||||
const __m128 r1 = k[blk_col][1]->f32_x[kc_col];
|
||||
const __m128 r2 = k[blk_col][2]->f32_x[kc_col];
|
||||
const __m128 r3 = k[blk_col][3]->f32_x[kc_col];
|
||||
|
||||
const __m256 top = _mm256_set_m128(r1, r0);
|
||||
const __m256 bot = _mm256_set_m128(r3, r2);
|
||||
|
||||
__m512 col = _mm512_castps256_ps512(top);
|
||||
col = _mm512_insertf32x8(col, bot, 1);
|
||||
|
||||
PANEL_COL_VEC((*panel), pc, 0) = col;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUILD_PANEL(512, double)
|
||||
{
|
||||
const int Q = 8; /* max(4, lanes) for double with ZMM -> 8 columns */
|
||||
|
||||
const int has_right = (col_index + 1) < col_length;
|
||||
const int has_bottom = (row_index + 1) < row_length;
|
||||
|
||||
const MAT_KERNEL(double) *const k_lt = matrix + (row_index * col_length + col_index);
|
||||
const MAT_KERNEL(double) *const k_rt =
|
||||
has_right ? (matrix + (row_index * col_length + (col_index + 1))) :
|
||||
(const MAT_KERNEL(double) *)&SN_ZERO_KERNEL;
|
||||
const MAT_KERNEL(double) *const k_lb =
|
||||
has_bottom ? (matrix + ((row_index + 1) * col_length + col_index)) :
|
||||
(const MAT_KERNEL(double) *)&SN_ZERO_KERNEL;
|
||||
const MAT_KERNEL(double) *const k_rb =
|
||||
(has_right && has_bottom) ?
|
||||
(matrix + ((row_index + 1) * col_length + (col_index + 1))) :
|
||||
(const MAT_KERNEL(double) *)&SN_ZERO_KERNEL;
|
||||
|
||||
for (int pc = 0; pc < Q; ++pc) {
|
||||
const int is_right_half = (pc >= 4);
|
||||
const int kc_col = pc & 3; /* column index inside 4x4 kernel */
|
||||
|
||||
const MAT_KERNEL(double) *src_top = is_right_half ? k_rt : k_lt;
|
||||
const MAT_KERNEL(double) *src_bot = is_right_half ? k_rb : k_lb;
|
||||
|
||||
const __m256d top256 = src_top->f64_y[kc_col];
|
||||
const __m256d bot256 = src_bot->f64_y[kc_col];
|
||||
|
||||
__m512d col = _mm512_castpd256_pd512(top256);
|
||||
col = _mm512_insertf64x4(col, bot256, 1);
|
||||
|
||||
PANEL_COL_VEC((*panel), pc, 0) = _mm512_castpd_ps(col);
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_STORE_PANEL(avx, float)
|
||||
{
|
||||
const int Q = 8; /* fixed for AVX float panel */
|
||||
|
||||
/* Local dummy kernel to swallow out-of-bounds writes; no init needed */
|
||||
MAT_KERNEL(float) zero;
|
||||
|
||||
const int has_right = (col_index + 1) < col_length;
|
||||
const int has_bottom = (row_index + 1) < row_length;
|
||||
|
||||
MAT_KERNEL(float) *const k_lt = (col_index < col_length && row_index < row_length) ?
|
||||
(matrix + (row_index * col_length + col_index)) :
|
||||
&zero;
|
||||
MAT_KERNEL(float) *const k_rt =
|
||||
has_right && (row_index < row_length) ?
|
||||
(matrix + (row_index * col_length + (col_index + 1))) :
|
||||
&zero;
|
||||
MAT_KERNEL(float) *const k_lb =
|
||||
has_bottom && (col_index < col_length) ?
|
||||
(matrix + ((row_index + 1) * col_length + col_index)) :
|
||||
&zero;
|
||||
MAT_KERNEL(float) *const k_rb =
|
||||
(has_right && has_bottom) ?
|
||||
(matrix + ((row_index + 1) * col_length + (col_index + 1))) :
|
||||
&zero;
|
||||
|
||||
register __m128 top128, bot128;
|
||||
int i = 0;
|
||||
for (; i < Q / 2; i++) {
|
||||
const int kc_col = i; /* column index inside 4x4 kernel */
|
||||
|
||||
/* Load the panel column vector */
|
||||
const __m256 col256 = PANEL_COL_VEC((*panel), i, 0);
|
||||
/* Split into top/bottom halves */
|
||||
top128 = _mm256_castps256_ps128(col256); /* low 128 */
|
||||
bot128 = _mm256_extractf128_ps(col256, 1); /* high 128 */
|
||||
|
||||
/* Store back into kernels directly (out-of-bounds writes go to dummy) */
|
||||
k_rt->f32_x[kc_col] = top128;
|
||||
k_rb->f32_x[kc_col] = bot128;
|
||||
}
|
||||
for (; i < Q; i++) {
|
||||
const int kc_col = i - 4; /* column index inside 4x4 kernel */
|
||||
|
||||
/* Load the panel column vector */
|
||||
const __m256 col256 = PANEL_COL_VEC((*panel), i, 0);
|
||||
/* Split into top/bottom halves */
|
||||
top128 = _mm256_castps256_ps128(col256); /* low 128 */
|
||||
bot128 = _mm256_extractf128_ps(col256, 1); /* high 128 */
|
||||
|
||||
/* Store back into kernels directly (out-of-bounds writes go to dummy) */
|
||||
k_lt->f32_x[kc_col] = top128;
|
||||
k_lb->f32_x[kc_col] = bot128;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_STORE_PANEL(512, float)
|
||||
{
|
||||
MAT_KERNEL(float) zero;
|
||||
MAT_KERNEL(float) * k[4][4];
|
||||
|
||||
for (int kc = 0; kc < 4; ++kc) {
|
||||
for (int kr = 0; kr < 4; ++kr) {
|
||||
const int col = col_index + kc;
|
||||
const int row = row_index + kr;
|
||||
k[kc][kr] = (col < col_length && row < row_length) ?
|
||||
(matrix + (row * col_length + col)) :
|
||||
&zero;
|
||||
}
|
||||
}
|
||||
|
||||
for (int pc = 0; pc < 16; ++pc) {
|
||||
const int blk_col = pc >> 2; /* which kernel column block (0..3) */
|
||||
const int kc_col = pc & 3; /* column inside a 4x4 kernel */
|
||||
|
||||
const __m512 col = PANEL_COL_VEC((*panel), pc, 0);
|
||||
|
||||
const __m256 top = _mm512_castps512_ps256(col);
|
||||
const __m256 bot = _mm512_extractf32x8_ps(col, 1);
|
||||
|
||||
const __m128 r0 = _mm256_castps256_ps128(top);
|
||||
const __m128 r1 = _mm256_extractf128_ps(top, 1);
|
||||
const __m128 r2 = _mm256_castps256_ps128(bot);
|
||||
const __m128 r3 = _mm256_extractf128_ps(bot, 1);
|
||||
|
||||
k[blk_col][0]->f32_x[kc_col] = r0;
|
||||
k[blk_col][1]->f32_x[kc_col] = r1;
|
||||
k[blk_col][2]->f32_x[kc_col] = r2;
|
||||
k[blk_col][3]->f32_x[kc_col] = r3;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_STORE_PANEL(sse, double)
|
||||
{
|
||||
MAT_KERNEL(double) *dst = matrix + (row_index * col_length + col_index);
|
||||
|
||||
for (int pc = 0; pc < 4; ++pc) {
|
||||
const int base = pc * 2;
|
||||
dst->f64_x[base] = _mm_castps_pd(PANEL_COL_VEC((*panel), pc, 0));
|
||||
dst->f64_x[base + 1] = _mm_castps_pd(PANEL_COL_VEC((*panel), pc, 1));
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_STORE_PANEL(avx, double)
|
||||
{
|
||||
const int Q = 8; /* fixed for AVX double panel */
|
||||
|
||||
MAT_KERNEL(double) zero;
|
||||
|
||||
const int has_right = (col_index + 1) < col_length;
|
||||
const int has_bottom = (row_index + 1) < row_length;
|
||||
|
||||
MAT_KERNEL(double) *const k_lt = (col_index < col_length && row_index < row_length) ?
|
||||
(matrix + (row_index * col_length + col_index)) :
|
||||
&zero;
|
||||
MAT_KERNEL(double) *const k_rt =
|
||||
has_right && (row_index < row_length) ?
|
||||
(matrix + (row_index * col_length + (col_index + 1))) :
|
||||
&zero;
|
||||
MAT_KERNEL(double) *const k_lb =
|
||||
has_bottom && (col_index < col_length) ?
|
||||
(matrix + ((row_index + 1) * col_length + col_index)) :
|
||||
&zero;
|
||||
MAT_KERNEL(double) *const k_rb =
|
||||
(has_right && has_bottom) ?
|
||||
(matrix + ((row_index + 1) * col_length + (col_index + 1))) :
|
||||
&zero;
|
||||
|
||||
for (int i = 0; i < Q; ++i) {
|
||||
const int kc_col = (i < 4) ? i : (i - 4);
|
||||
const __m256 top_chunk = PANEL_COL_VEC((*panel), i, 0);
|
||||
const __m256 bot_chunk = PANEL_COL_VEC((*panel), i, 1);
|
||||
|
||||
MAT_KERNEL(double) *const top_dst = (i < 4) ? k_rt : k_lt;
|
||||
MAT_KERNEL(double) *const bot_dst = (i < 4) ? k_rb : k_lb;
|
||||
|
||||
top_dst->f64_y[kc_col] = _mm256_castps_pd(top_chunk);
|
||||
bot_dst->f64_y[kc_col] = _mm256_castps_pd(bot_chunk);
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_STORE_PANEL(512, double)
|
||||
{
|
||||
const int Q = 8; /* max(4, lanes) -> 8 columns, one ZMM per column */
|
||||
|
||||
MAT_KERNEL(double) zero;
|
||||
|
||||
const int has_right = (col_index + 1) < col_length;
|
||||
const int has_bottom = (row_index + 1) < row_length;
|
||||
|
||||
MAT_KERNEL(double) *const k_lt = (col_index < col_length && row_index < row_length) ?
|
||||
(matrix + (row_index * col_length + col_index)) :
|
||||
&zero;
|
||||
MAT_KERNEL(double) *const k_rt =
|
||||
has_right && (row_index < row_length) ?
|
||||
(matrix + (row_index * col_length + (col_index + 1))) :
|
||||
&zero;
|
||||
MAT_KERNEL(double) *const k_lb =
|
||||
has_bottom && (col_index < col_length) ?
|
||||
(matrix + ((row_index + 1) * col_length + col_index)) :
|
||||
&zero;
|
||||
MAT_KERNEL(double) *const k_rb =
|
||||
(has_right && has_bottom) ?
|
||||
(matrix + ((row_index + 1) * col_length + (col_index + 1))) :
|
||||
&zero;
|
||||
|
||||
for (int i = 0; i < Q; ++i) {
|
||||
const int kc_col = (i < 4) ? i : (i - 4);
|
||||
const __m512 col = PANEL_COL_VEC((*panel), i, 0);
|
||||
const __m512d col_pd = _mm512_castps_pd(col);
|
||||
|
||||
const __m256d top256 = _mm512_castpd512_pd256(col_pd);
|
||||
const __m256d bot256 = _mm512_extractf64x4_pd(col_pd, 1);
|
||||
|
||||
MAT_KERNEL(double) *const top_dst = (i < 4) ? k_rt : k_lt;
|
||||
MAT_KERNEL(double) *const bot_dst = (i < 4) ? k_rb : k_lb;
|
||||
|
||||
top_dst->f64_y[kc_col] = top256;
|
||||
bot_dst->f64_y[kc_col] = bot256;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_matkernel.h"
|
||||
|
||||
DECLARE_BUILD_PANEL(avx, float)
|
||||
{
|
||||
const int Q = 8; /* fixed for AVX float panel */
|
||||
|
||||
/* Neighbor kernels; substitute global zero kernel where out-of-bounds */
|
||||
const int has_right = (col_index + 1) < col_length;
|
||||
const int has_bottom = (row_index + 1) < row_length;
|
||||
|
||||
const MAT_KERNEL(float) *const k_lt = matrix + (row_index * col_length + col_index);
|
||||
const MAT_KERNEL(float) *const k_rt =
|
||||
has_right ? (matrix + (row_index * col_length + (col_index + 1))) :
|
||||
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
|
||||
const MAT_KERNEL(float) *const k_lb =
|
||||
has_bottom ? (matrix + ((row_index + 1) * col_length + col_index)) :
|
||||
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
|
||||
const MAT_KERNEL(float) *const k_rb =
|
||||
(has_right && has_bottom) ?
|
||||
(matrix + ((row_index + 1) * col_length + (col_index + 1))) :
|
||||
(const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
|
||||
|
||||
register __m128 top128, bot128;
|
||||
register __m256 col256;
|
||||
|
||||
for (int pc = 0; pc < Q; ++pc) {
|
||||
const int is_right_half = (pc >= 4);
|
||||
const int kc_col = pc & 3; /* column index inside 4x4 kernel */
|
||||
|
||||
const MAT_KERNEL(float) *src_top = is_right_half ? k_rt : k_lt;
|
||||
const MAT_KERNEL(float) *src_bot = is_right_half ? k_rb : k_lb;
|
||||
|
||||
/* Vector loads: each kernel column is a compact __m128 */
|
||||
top128 = src_top->f32_x[kc_col];
|
||||
bot128 = src_bot->f32_x[kc_col];
|
||||
|
||||
/* Combine into an AVX column: low 128 = top, high 128 = bottom */
|
||||
col256 = _mm256_set_m128(bot128, top128);
|
||||
|
||||
PANEL_COL_VEC((*panel), pc, 0) = col256;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUILD_PANEL(512, float)
|
||||
{
|
||||
const MAT_KERNEL(float) *const zero = (const MAT_KERNEL(float) *)&SN_ZERO_KERNEL;
|
||||
const MAT_KERNEL(float) * k[4][4];
|
||||
|
||||
for (int kc = 0; kc < 4; ++kc) {
|
||||
for (int kr = 0; kr < 4; ++kr) {
|
||||
const int col = col_index + kc;
|
||||
const int row = row_index + kr;
|
||||
k[kc][kr] = (col < col_length && row < row_length) ?
|
||||
(matrix + (row * col_length + col)) :
|
||||
zero;
|
||||
}
|
||||
}
|
||||
|
||||
/* Each panel column corresponds to a kernel column (0..3) within a block col (0..3). */
|
||||
for (int pc = 0; pc < 16; ++pc) {
|
||||
const int blk_col = pc >> 2; /* which kernel column block (0..3) */
|
||||
const int kc_col = pc & 3; /* column inside a 4x4 kernel */
|
||||
|
||||
const __m128 r0 = k[blk_col][0]->f32_x[kc_col];
|
||||
const __m128 r1 = k[blk_col][1]->f32_x[kc_col];
|
||||
const __m128 r2 = k[blk_col][2]->f32_x[kc_col];
|
||||
const __m128 r3 = k[blk_col][3]->f32_x[kc_col];
|
||||
|
||||
const __m256 top = _mm256_set_m128(r1, r0);
|
||||
const __m256 bot = _mm256_set_m128(r3, r2);
|
||||
|
||||
__m512 col = _mm512_castps256_ps512(top);
|
||||
col = _mm512_insertf32x8(col, bot, 1);
|
||||
|
||||
PANEL_COL_VEC((*panel), pc, 0) = col;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_BUILD_PANEL(512, double)
|
||||
{
|
||||
const int Q = 8; /* max(4, lanes) for double with ZMM -> 8 columns */
|
||||
|
||||
const int has_right = (col_index + 1) < col_length;
|
||||
const int has_bottom = (row_index + 1) < row_length;
|
||||
|
||||
const MAT_KERNEL(double) *const k_lt = matrix + (row_index * col_length + col_index);
|
||||
const MAT_KERNEL(double) *const k_rt =
|
||||
has_right ? (matrix + (row_index * col_length + (col_index + 1))) :
|
||||
(const MAT_KERNEL(double) *)&SN_ZERO_KERNEL;
|
||||
const MAT_KERNEL(double) *const k_lb =
|
||||
has_bottom ? (matrix + ((row_index + 1) * col_length + col_index)) :
|
||||
(const MAT_KERNEL(double) *)&SN_ZERO_KERNEL;
|
||||
const MAT_KERNEL(double) *const k_rb =
|
||||
(has_right && has_bottom) ?
|
||||
(matrix + ((row_index + 1) * col_length + (col_index + 1))) :
|
||||
(const MAT_KERNEL(double) *)&SN_ZERO_KERNEL;
|
||||
|
||||
for (int pc = 0; pc < Q; ++pc) {
|
||||
const int is_right_half = (pc >= 4);
|
||||
const int kc_col = pc & 3; /* column index inside 4x4 kernel */
|
||||
|
||||
const MAT_KERNEL(double) *src_top = is_right_half ? k_rt : k_lt;
|
||||
const MAT_KERNEL(double) *src_bot = is_right_half ? k_rb : k_lb;
|
||||
|
||||
const __m256d top256 = src_top->f64_y[kc_col];
|
||||
const __m256d bot256 = src_bot->f64_y[kc_col];
|
||||
|
||||
__m512d col = _mm512_castpd256_pd512(top256);
|
||||
col = _mm512_insertf64x4(col, bot256, 1);
|
||||
|
||||
PANEL_COL_VEC((*panel), pc, 0) = _mm512_castpd_ps(col);
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_STORE_PANEL(avx, float)
|
||||
{
|
||||
const int Q = 8; /* fixed for AVX float panel */
|
||||
|
||||
/* Local dummy kernel to swallow out-of-bounds writes; no init needed */
|
||||
MAT_KERNEL(float) zero;
|
||||
|
||||
const int has_right = (col_index + 1) < col_length;
|
||||
const int has_bottom = (row_index + 1) < row_length;
|
||||
|
||||
MAT_KERNEL(float) *const k_lt = (col_index < col_length && row_index < row_length) ?
|
||||
(matrix + (row_index * col_length + col_index)) :
|
||||
&zero;
|
||||
MAT_KERNEL(float) *const k_rt =
|
||||
has_right && (row_index < row_length) ?
|
||||
(matrix + (row_index * col_length + (col_index + 1))) :
|
||||
&zero;
|
||||
MAT_KERNEL(float) *const k_lb =
|
||||
has_bottom && (col_index < col_length) ?
|
||||
(matrix + ((row_index + 1) * col_length + col_index)) :
|
||||
&zero;
|
||||
MAT_KERNEL(float) *const k_rb =
|
||||
(has_right && has_bottom) ?
|
||||
(matrix + ((row_index + 1) * col_length + (col_index + 1))) :
|
||||
&zero;
|
||||
|
||||
register __m128 top128, bot128;
|
||||
int i = 0;
|
||||
for (; i < Q / 2; i++) {
|
||||
const int kc_col = i; /* column index inside 4x4 kernel */
|
||||
|
||||
/* Load the panel column vector */
|
||||
const __m256 col256 = PANEL_COL_VEC((*panel), i, 0);
|
||||
/* Split into top/bottom halves */
|
||||
top128 = _mm256_castps256_ps128(col256); /* low 128 */
|
||||
bot128 = _mm256_extractf128_ps(col256, 1); /* high 128 */
|
||||
|
||||
/* Store back into kernels directly (out-of-bounds writes go to dummy) */
|
||||
k_rt->f32_x[kc_col] = top128;
|
||||
k_rb->f32_x[kc_col] = bot128;
|
||||
}
|
||||
for (; i < Q; i++) {
|
||||
const int kc_col = i - 4; /* column index inside 4x4 kernel */
|
||||
|
||||
/* Load the panel column vector */
|
||||
const __m256 col256 = PANEL_COL_VEC((*panel), i, 0);
|
||||
/* Split into top/bottom halves */
|
||||
top128 = _mm256_castps256_ps128(col256); /* low 128 */
|
||||
bot128 = _mm256_extractf128_ps(col256, 1); /* high 128 */
|
||||
|
||||
/* Store back into kernels directly (out-of-bounds writes go to dummy) */
|
||||
k_lt->f32_x[kc_col] = top128;
|
||||
k_lb->f32_x[kc_col] = bot128;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_STORE_PANEL(512, float)
|
||||
{
|
||||
MAT_KERNEL(float) zero;
|
||||
MAT_KERNEL(float) * k[4][4];
|
||||
|
||||
for (int kc = 0; kc < 4; ++kc) {
|
||||
for (int kr = 0; kr < 4; ++kr) {
|
||||
const int col = col_index + kc;
|
||||
const int row = row_index + kr;
|
||||
k[kc][kr] = (col < col_length && row < row_length) ?
|
||||
(matrix + (row * col_length + col)) :
|
||||
&zero;
|
||||
}
|
||||
}
|
||||
|
||||
for (int pc = 0; pc < 16; ++pc) {
|
||||
const int blk_col = pc >> 2; /* which kernel column block (0..3) */
|
||||
const int kc_col = pc & 3; /* column inside a 4x4 kernel */
|
||||
|
||||
const __m512 col = PANEL_COL_VEC((*panel), pc, 0);
|
||||
|
||||
const __m256 top = _mm512_castps512_ps256(col);
|
||||
const __m256 bot = _mm512_extractf32x8_ps(col, 1);
|
||||
|
||||
const __m128 r0 = _mm256_castps256_ps128(top);
|
||||
const __m128 r1 = _mm256_extractf128_ps(top, 1);
|
||||
const __m128 r2 = _mm256_castps256_ps128(bot);
|
||||
const __m128 r3 = _mm256_extractf128_ps(bot, 1);
|
||||
|
||||
k[blk_col][0]->f32_x[kc_col] = r0;
|
||||
k[blk_col][1]->f32_x[kc_col] = r1;
|
||||
k[blk_col][2]->f32_x[kc_col] = r2;
|
||||
k[blk_col][3]->f32_x[kc_col] = r3;
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_STORE_PANEL(sse, double)
|
||||
{
|
||||
MAT_KERNEL(double) *dst = matrix + (row_index * col_length + col_index);
|
||||
|
||||
for (int pc = 0; pc < 4; ++pc) {
|
||||
const int base = pc * 2;
|
||||
dst->f64_x[base] = _mm_castps_pd(PANEL_COL_VEC((*panel), pc, 0));
|
||||
dst->f64_x[base + 1] = _mm_castps_pd(PANEL_COL_VEC((*panel), pc, 1));
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_STORE_PANEL(avx, double)
|
||||
{
|
||||
const int Q = 8; /* fixed for AVX double panel */
|
||||
|
||||
MAT_KERNEL(double) zero;
|
||||
|
||||
const int has_right = (col_index + 1) < col_length;
|
||||
const int has_bottom = (row_index + 1) < row_length;
|
||||
|
||||
MAT_KERNEL(double) *const k_lt = (col_index < col_length && row_index < row_length) ?
|
||||
(matrix + (row_index * col_length + col_index)) :
|
||||
&zero;
|
||||
MAT_KERNEL(double) *const k_rt =
|
||||
has_right && (row_index < row_length) ?
|
||||
(matrix + (row_index * col_length + (col_index + 1))) :
|
||||
&zero;
|
||||
MAT_KERNEL(double) *const k_lb =
|
||||
has_bottom && (col_index < col_length) ?
|
||||
(matrix + ((row_index + 1) * col_length + col_index)) :
|
||||
&zero;
|
||||
MAT_KERNEL(double) *const k_rb =
|
||||
(has_right && has_bottom) ?
|
||||
(matrix + ((row_index + 1) * col_length + (col_index + 1))) :
|
||||
&zero;
|
||||
|
||||
for (int i = 0; i < Q; ++i) {
|
||||
const int kc_col = (i < 4) ? i : (i - 4);
|
||||
const __m256 top_chunk = PANEL_COL_VEC((*panel), i, 0);
|
||||
const __m256 bot_chunk = PANEL_COL_VEC((*panel), i, 1);
|
||||
|
||||
MAT_KERNEL(double) *const top_dst = (i < 4) ? k_rt : k_lt;
|
||||
MAT_KERNEL(double) *const bot_dst = (i < 4) ? k_rb : k_lb;
|
||||
|
||||
top_dst->f64_y[kc_col] = _mm256_castps_pd(top_chunk);
|
||||
bot_dst->f64_y[kc_col] = _mm256_castps_pd(bot_chunk);
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_STORE_PANEL(512, double)
|
||||
{
|
||||
const int Q = 8; /* max(4, lanes) -> 8 columns, one ZMM per column */
|
||||
|
||||
MAT_KERNEL(double) zero;
|
||||
|
||||
const int has_right = (col_index + 1) < col_length;
|
||||
const int has_bottom = (row_index + 1) < row_length;
|
||||
|
||||
MAT_KERNEL(double) *const k_lt = (col_index < col_length && row_index < row_length) ?
|
||||
(matrix + (row_index * col_length + col_index)) :
|
||||
&zero;
|
||||
MAT_KERNEL(double) *const k_rt =
|
||||
has_right && (row_index < row_length) ?
|
||||
(matrix + (row_index * col_length + (col_index + 1))) :
|
||||
&zero;
|
||||
MAT_KERNEL(double) *const k_lb =
|
||||
has_bottom && (col_index < col_length) ?
|
||||
(matrix + ((row_index + 1) * col_length + col_index)) :
|
||||
&zero;
|
||||
MAT_KERNEL(double) *const k_rb =
|
||||
(has_right && has_bottom) ?
|
||||
(matrix + ((row_index + 1) * col_length + (col_index + 1))) :
|
||||
&zero;
|
||||
|
||||
for (int i = 0; i < Q; ++i) {
|
||||
const int kc_col = (i < 4) ? i : (i - 4);
|
||||
const __m512 col = PANEL_COL_VEC((*panel), i, 0);
|
||||
const __m512d col_pd = _mm512_castps_pd(col);
|
||||
|
||||
const __m256d top256 = _mm512_castpd512_pd256(col_pd);
|
||||
const __m256d bot256 = _mm512_extractf64x4_pd(col_pd, 1);
|
||||
|
||||
MAT_KERNEL(double) *const top_dst = (i < 4) ? k_rt : k_lt;
|
||||
MAT_KERNEL(double) *const bot_dst = (i < 4) ? k_rb : k_lb;
|
||||
|
||||
top_dst->f64_y[kc_col] = top256;
|
||||
bot_dst->f64_y[kc_col] = bot256;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,180 +1,180 @@
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrinsic.h"
|
||||
#include <math.h>
|
||||
|
||||
static const float quality_threshold = 1e-6f;
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS_SCALAR(float, sse, , try_plu)
|
||||
{
|
||||
/* Aliases */
|
||||
MAT_KERNEL(float) *upper = left; /* U */
|
||||
MAT_KERNEL(float) *lower = right; /* L (unit diag) */
|
||||
MAT_KERNEL(float) *source = ans; /* A */
|
||||
unsigned char *pivot = (unsigned char *)&scalar->data[0]; /* length = 4 */
|
||||
int *success = (int *)&scalar->data[1];
|
||||
|
||||
/* Init permutation and outputs */
|
||||
pivot[0] = 0;
|
||||
pivot[1] = 1;
|
||||
pivot[2] = 2;
|
||||
pivot[3] = 3;
|
||||
*success = 1;
|
||||
|
||||
/* Working copy of A in column-major a[col][row], load via SIMD view */
|
||||
MAT_KERNEL(float) a;
|
||||
const __m128 z = _mm_setzero_ps();
|
||||
for (int c = 0; c < 4; ++c) {
|
||||
__m128 col = _mm_load_ps((float *)&source->f32_x[c]);
|
||||
_mm_storeu_ps((float *)&a.f32_x[c], col);
|
||||
_mm_store_ps((float *)&upper->f32_x[c], z);
|
||||
_mm_store_ps((float *)&lower->f32_x[c], z);
|
||||
}
|
||||
|
||||
const float eps = 1e-12f;
|
||||
|
||||
for (int k = 0; k < 4; ++k) {
|
||||
/* Pivot search on column k, rows k..3 */
|
||||
int p = k;
|
||||
float maxabs = fabsf(a.m[k][p]);
|
||||
for (int r = k + 1; r < 4; ++r) {
|
||||
float v = fabsf(a.m[k][r]);
|
||||
if (v > maxabs) {
|
||||
maxabs = v;
|
||||
p = r;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxabs < eps) {
|
||||
*success = 0;
|
||||
/* leave outputs zeroed */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Swap rows if needed */
|
||||
if (p != k) {
|
||||
for (int c = 0; c < 4; ++c) {
|
||||
float tmp = a.m[c][k];
|
||||
a.m[c][k] = a.m[c][p];
|
||||
a.m[c][p] = tmp;
|
||||
}
|
||||
unsigned char tmpi = pivot[k];
|
||||
pivot[k] = pivot[p];
|
||||
pivot[p] = tmpi;
|
||||
}
|
||||
|
||||
float pivot_val = a.m[k][k];
|
||||
|
||||
/* Eliminate below pivot: store multipliers in L column k */
|
||||
for (int r = k + 1; r < 4; ++r) {
|
||||
float factor = a.m[k][r] / pivot_val;
|
||||
lower->m[k][r] = factor;
|
||||
for (int c = k; c < 4; ++c) {
|
||||
a.m[c][r] -= factor * a.m[c][k];
|
||||
}
|
||||
}
|
||||
|
||||
/* Set U row k (columns k..3) and L diagonal */
|
||||
lower->m[k][k] = 1.0f;
|
||||
for (int c = k; c < 4; ++c) {
|
||||
upper->m[c][k] = a.m[c][k];
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure remaining diagonal ones for L */
|
||||
for (int d = 0; d < 4; ++d) {
|
||||
if (lower->m[d][d] == 0.0f)
|
||||
lower->m[d][d] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
#define DOT_F32_SSE(a, b, ans) \
|
||||
do { \
|
||||
__m128 _p = _mm_mul_ps((a), (b)); /* p0 p1 p2 p3 */ \
|
||||
__m128 _t = _mm_shuffle_ps(_p, _p, _MM_SHUFFLE(2, 3, 0, 1)); \
|
||||
_p = _mm_add_ps(_p, _t); \
|
||||
_t = _mm_movehl_ps(_t, _p); \
|
||||
ans = _mm_cvtss_f32(_mm_add_ss(_p, _t)); \
|
||||
} while (0)
|
||||
|
||||
#define FIND_MAX_F32_SSE(a, b) \
|
||||
do { \
|
||||
__m128 _t = _mm_movehl_ps(a, a); \
|
||||
a = _mm_max_ps(a, _t); \
|
||||
_t = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 0, 1)); \
|
||||
b = _mm_max_ps(a, _t); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* layout of scalarpack:
|
||||
*
|
||||
*/
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, sse, , quality)
|
||||
{
|
||||
static const __m128 tiny_source = { .m128_f32 = { 1e-6f, 1e-6f, 1e-6f, 1e-6f } };
|
||||
|
||||
register __m128 tiny = _mm_load_ps(tiny_source.m128_f32);
|
||||
|
||||
register __m128 col0 = _mm_load_ps((float *)&right->f32_x[0]);
|
||||
register __m128 col1 = _mm_load_ps((float *)&right->f32_x[1]);
|
||||
register __m128 col2 = _mm_load_ps((float *)&right->f32_x[2]);
|
||||
register __m128 col3 = _mm_load_ps((float *)&right->f32_x[3]);
|
||||
|
||||
__m128 self_dot_src = { 0 };
|
||||
// try in reigister mix later
|
||||
DOT_F32_SSE(col0, col0, self_dot_src.m128_f32[0]);
|
||||
DOT_F32_SSE(col1, col1, self_dot_src.m128_f32[1]);
|
||||
DOT_F32_SSE(col2, col2, self_dot_src.m128_f32[2]);
|
||||
DOT_F32_SSE(col3, col3, self_dot_src.m128_f32[3]);
|
||||
|
||||
register __m128 self_dot = _mm_load_ps(self_dot_src.m128_f32);
|
||||
|
||||
register __m128 max;
|
||||
FIND_MAX_F32_SSE(self_dot, max);
|
||||
//float norm = _mm_cvtss_f32(max);
|
||||
|
||||
// min on cross
|
||||
register __m128 col_shuff_1 = _mm_shuffle_ps(col1, col1, _MM_SHUFFLE(0, 3, 2, 1));
|
||||
register __m128 col_shuff_2 = _mm_shuffle_ps(col2, col2, _MM_SHUFFLE(1, 0, 3, 2));
|
||||
register __m128 col_shuff_3 = _mm_shuffle_ps(col3, col3, _MM_SHUFFLE(2, 1, 0, 3));
|
||||
register __m128 min = _mm_min_ps(col0, col_shuff_1);
|
||||
register __m128 min0 = _mm_min_ps(col_shuff_2, col_shuff_3);
|
||||
min = _mm_min_ps(min, min0);
|
||||
|
||||
float quality = _mm_cvtss_f32(_mm_div_ps(min, _mm_add_ps(max, tiny)));
|
||||
ans->f32_x[0].m128_f32[0] = quality;
|
||||
if (quality < quality_threshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
__m128 cross_dot_src[2];
|
||||
DOT_F32_SSE(col0, col1, cross_dot_src[0].m128_f32[0]);
|
||||
DOT_F32_SSE(col0, col2, cross_dot_src[0].m128_f32[1]);
|
||||
DOT_F32_SSE(col0, col3, cross_dot_src[0].m128_f32[2]);
|
||||
DOT_F32_SSE(col1, col2, cross_dot_src[0].m128_f32[3]);
|
||||
DOT_F32_SSE(col1, col3, cross_dot_src[1].m128_f32[0]);
|
||||
DOT_F32_SSE(col2, col3, cross_dot_src[1].m128_f32[1]);
|
||||
|
||||
register __m128 cross_dot_0 = _mm_load_ps(cross_dot_src[0].m128_f32);
|
||||
register __m128 cross_dot_1 = _mm_load_ps(cross_dot_src[1].m128_f32);
|
||||
|
||||
register __m128 base_0 = _mm_shuffle_ps(self_dot, self_dot, _MM_SHUFFLE(1, 0, 0, 0));
|
||||
register __m128 base_1 = _mm_shuffle_ps(self_dot, self_dot, _MM_SHUFFLE(3, 3, 2, 1));
|
||||
|
||||
register __m128 relation_0 =
|
||||
_mm_div_ps(cross_dot_0, _mm_add_ps(_mm_mul_ps(base_0, base_1), tiny));
|
||||
|
||||
base_0 = _mm_shuffle_ps(self_dot, self_dot, _MM_SHUFFLE(2, 3, 2, 1));
|
||||
base_1 = _mm_shuffle_ps(self_dot, self_dot, _MM_SHUFFLE(3, 3, 3, 3));
|
||||
|
||||
register __m128 relation_1 =
|
||||
_mm_div_ps(cross_dot_0, _mm_add_ps(_mm_mul_ps(base_0, base_1), tiny));
|
||||
|
||||
relation_0 = _mm_max_ps(relation_0, relation_1);
|
||||
FIND_MAX_F32_SSE(relation_0, relation_0);
|
||||
ans->f32_x[0].m128_f32[1] = _mm_cvtss_f32(relation_0);
|
||||
}
|
||||
|
||||
#endif
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrinsic.h"
|
||||
#include <math.h>
|
||||
|
||||
static const float quality_threshold = 1e-6f;
|
||||
|
||||
DECLARE_KER_PROC_LEFT_RIGHT_ANS_SCALAR(float, sse, , try_plu)
|
||||
{
|
||||
/* Aliases */
|
||||
MAT_KERNEL(float) *upper = left; /* U */
|
||||
MAT_KERNEL(float) *lower = right; /* L (unit diag) */
|
||||
MAT_KERNEL(float) *source = ans; /* A */
|
||||
unsigned char *pivot = (unsigned char *)&scalar->data[0]; /* length = 4 */
|
||||
int *success = (int *)&scalar->data[1];
|
||||
|
||||
/* Init permutation and outputs */
|
||||
pivot[0] = 0;
|
||||
pivot[1] = 1;
|
||||
pivot[2] = 2;
|
||||
pivot[3] = 3;
|
||||
*success = 1;
|
||||
|
||||
/* Working copy of A in column-major a[col][row], load via SIMD view */
|
||||
MAT_KERNEL(float) a;
|
||||
const __m128 z = _mm_setzero_ps();
|
||||
for (int c = 0; c < 4; ++c) {
|
||||
__m128 col = _mm_load_ps((float *)&source->f32_x[c]);
|
||||
_mm_storeu_ps((float *)&a.f32_x[c], col);
|
||||
_mm_store_ps((float *)&upper->f32_x[c], z);
|
||||
_mm_store_ps((float *)&lower->f32_x[c], z);
|
||||
}
|
||||
|
||||
const float eps = 1e-12f;
|
||||
|
||||
for (int k = 0; k < 4; ++k) {
|
||||
/* Pivot search on column k, rows k..3 */
|
||||
int p = k;
|
||||
float maxabs = fabsf(a.m[k][p]);
|
||||
for (int r = k + 1; r < 4; ++r) {
|
||||
float v = fabsf(a.m[k][r]);
|
||||
if (v > maxabs) {
|
||||
maxabs = v;
|
||||
p = r;
|
||||
}
|
||||
}
|
||||
|
||||
if (maxabs < eps) {
|
||||
*success = 0;
|
||||
/* leave outputs zeroed */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Swap rows if needed */
|
||||
if (p != k) {
|
||||
for (int c = 0; c < 4; ++c) {
|
||||
float tmp = a.m[c][k];
|
||||
a.m[c][k] = a.m[c][p];
|
||||
a.m[c][p] = tmp;
|
||||
}
|
||||
unsigned char tmpi = pivot[k];
|
||||
pivot[k] = pivot[p];
|
||||
pivot[p] = tmpi;
|
||||
}
|
||||
|
||||
float pivot_val = a.m[k][k];
|
||||
|
||||
/* Eliminate below pivot: store multipliers in L column k */
|
||||
for (int r = k + 1; r < 4; ++r) {
|
||||
float factor = a.m[k][r] / pivot_val;
|
||||
lower->m[k][r] = factor;
|
||||
for (int c = k; c < 4; ++c) {
|
||||
a.m[c][r] -= factor * a.m[c][k];
|
||||
}
|
||||
}
|
||||
|
||||
/* Set U row k (columns k..3) and L diagonal */
|
||||
lower->m[k][k] = 1.0f;
|
||||
for (int c = k; c < 4; ++c) {
|
||||
upper->m[c][k] = a.m[c][k];
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensure remaining diagonal ones for L */
|
||||
for (int d = 0; d < 4; ++d) {
|
||||
if (lower->m[d][d] == 0.0f)
|
||||
lower->m[d][d] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
#define DOT_F32_SSE(a, b, ans) \
|
||||
do { \
|
||||
__m128 _p = _mm_mul_ps((a), (b)); /* p0 p1 p2 p3 */ \
|
||||
__m128 _t = _mm_shuffle_ps(_p, _p, _MM_SHUFFLE(2, 3, 0, 1)); \
|
||||
_p = _mm_add_ps(_p, _t); \
|
||||
_t = _mm_movehl_ps(_t, _p); \
|
||||
ans = _mm_cvtss_f32(_mm_add_ss(_p, _t)); \
|
||||
} while (0)
|
||||
|
||||
#define FIND_MAX_F32_SSE(a, b) \
|
||||
do { \
|
||||
__m128 _t = _mm_movehl_ps(a, a); \
|
||||
a = _mm_max_ps(a, _t); \
|
||||
_t = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 0, 1)); \
|
||||
b = _mm_max_ps(a, _t); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* layout of scalarpack:
|
||||
*
|
||||
*/
|
||||
DECLARE_KER_PROC_RIGHT_ANS(float, sse, , quality)
|
||||
{
|
||||
static const __m128 tiny_source = { .m128_f32 = { 1e-6f, 1e-6f, 1e-6f, 1e-6f } };
|
||||
|
||||
register __m128 tiny = _mm_load_ps(tiny_source.m128_f32);
|
||||
|
||||
register __m128 col0 = _mm_load_ps((float *)&right->f32_x[0]);
|
||||
register __m128 col1 = _mm_load_ps((float *)&right->f32_x[1]);
|
||||
register __m128 col2 = _mm_load_ps((float *)&right->f32_x[2]);
|
||||
register __m128 col3 = _mm_load_ps((float *)&right->f32_x[3]);
|
||||
|
||||
__m128 self_dot_src = { 0 };
|
||||
// try in reigister mix later
|
||||
DOT_F32_SSE(col0, col0, self_dot_src.m128_f32[0]);
|
||||
DOT_F32_SSE(col1, col1, self_dot_src.m128_f32[1]);
|
||||
DOT_F32_SSE(col2, col2, self_dot_src.m128_f32[2]);
|
||||
DOT_F32_SSE(col3, col3, self_dot_src.m128_f32[3]);
|
||||
|
||||
register __m128 self_dot = _mm_load_ps(self_dot_src.m128_f32);
|
||||
|
||||
register __m128 max;
|
||||
FIND_MAX_F32_SSE(self_dot, max);
|
||||
//float norm = _mm_cvtss_f32(max);
|
||||
|
||||
// min on cross
|
||||
register __m128 col_shuff_1 = _mm_shuffle_ps(col1, col1, _MM_SHUFFLE(0, 3, 2, 1));
|
||||
register __m128 col_shuff_2 = _mm_shuffle_ps(col2, col2, _MM_SHUFFLE(1, 0, 3, 2));
|
||||
register __m128 col_shuff_3 = _mm_shuffle_ps(col3, col3, _MM_SHUFFLE(2, 1, 0, 3));
|
||||
register __m128 min = _mm_min_ps(col0, col_shuff_1);
|
||||
register __m128 min0 = _mm_min_ps(col_shuff_2, col_shuff_3);
|
||||
min = _mm_min_ps(min, min0);
|
||||
|
||||
float quality = _mm_cvtss_f32(_mm_div_ps(min, _mm_add_ps(max, tiny)));
|
||||
ans->f32_x[0].m128_f32[0] = quality;
|
||||
if (quality < quality_threshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
__m128 cross_dot_src[2];
|
||||
DOT_F32_SSE(col0, col1, cross_dot_src[0].m128_f32[0]);
|
||||
DOT_F32_SSE(col0, col2, cross_dot_src[0].m128_f32[1]);
|
||||
DOT_F32_SSE(col0, col3, cross_dot_src[0].m128_f32[2]);
|
||||
DOT_F32_SSE(col1, col2, cross_dot_src[0].m128_f32[3]);
|
||||
DOT_F32_SSE(col1, col3, cross_dot_src[1].m128_f32[0]);
|
||||
DOT_F32_SSE(col2, col3, cross_dot_src[1].m128_f32[1]);
|
||||
|
||||
register __m128 cross_dot_0 = _mm_load_ps(cross_dot_src[0].m128_f32);
|
||||
register __m128 cross_dot_1 = _mm_load_ps(cross_dot_src[1].m128_f32);
|
||||
|
||||
register __m128 base_0 = _mm_shuffle_ps(self_dot, self_dot, _MM_SHUFFLE(1, 0, 0, 0));
|
||||
register __m128 base_1 = _mm_shuffle_ps(self_dot, self_dot, _MM_SHUFFLE(3, 3, 2, 1));
|
||||
|
||||
register __m128 relation_0 =
|
||||
_mm_div_ps(cross_dot_0, _mm_add_ps(_mm_mul_ps(base_0, base_1), tiny));
|
||||
|
||||
base_0 = _mm_shuffle_ps(self_dot, self_dot, _MM_SHUFFLE(2, 3, 2, 1));
|
||||
base_1 = _mm_shuffle_ps(self_dot, self_dot, _MM_SHUFFLE(3, 3, 3, 3));
|
||||
|
||||
register __m128 relation_1 =
|
||||
_mm_div_ps(cross_dot_0, _mm_add_ps(_mm_mul_ps(base_0, base_1), tiny));
|
||||
|
||||
relation_0 = _mm_max_ps(relation_0, relation_1);
|
||||
FIND_MAX_F32_SSE(relation_0, relation_0);
|
||||
ans->f32_x[0].m128_f32[1] = _mm_cvtss_f32(relation_0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_internal.h"
|
||||
#include "sn_intrinsic.h"
|
||||
|
||||
INTERNAL __m128i facIncrement = { 4, 4, 4, 4 };
|
||||
INTERNAL __m128i facBase = { 1, 2, 3, 4 };
|
||||
|
||||
INTERNAL uint64_t SN_DECL factorial_simd_sse(int n)
|
||||
{
|
||||
__m128i baseResult = facBase;
|
||||
__m128i facBaseLocal = facBase;
|
||||
const int cycle = (n - 3) >> 2;
|
||||
const uint32_t rest = (cycle << 2) + 1;
|
||||
for (size_t i = 0; i < cycle; i++) {
|
||||
facBaseLocal = _mm_add_epi32(facBaseLocal, facIncrement);
|
||||
baseResult = _mm_mullo_epi32(baseResult, facBaseLocal);
|
||||
}
|
||||
uint64_t result = (uint64_t)baseResult.m128i_i32[0] * (uint64_t)baseResult.m128i_i32[1] *
|
||||
(uint64_t)baseResult.m128i_i32[2] * (uint64_t)baseResult.m128i_i32[3];
|
||||
for (uint64_t i = rest; i < n; i++) {
|
||||
result *= i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_internal.h"
|
||||
#include "sn_intrinsic.h"
|
||||
|
||||
INTERNAL __m128i facIncrement = { 4, 4, 4, 4 };
|
||||
INTERNAL __m128i facBase = { 1, 2, 3, 4 };
|
||||
|
||||
INTERNAL uint64_t SN_DECL factorial_simd_sse(int n)
|
||||
{
|
||||
__m128i baseResult = facBase;
|
||||
__m128i facBaseLocal = facBase;
|
||||
const int cycle = (n - 3) >> 2;
|
||||
const uint32_t rest = (cycle << 2) + 1;
|
||||
for (size_t i = 0; i < cycle; i++) {
|
||||
facBaseLocal = _mm_add_epi32(facBaseLocal, facIncrement);
|
||||
baseResult = _mm_mullo_epi32(baseResult, facBaseLocal);
|
||||
}
|
||||
uint64_t result = (uint64_t)baseResult.m128i_i32[0] * (uint64_t)baseResult.m128i_i32[1] *
|
||||
(uint64_t)baseResult.m128i_i32[2] * (uint64_t)baseResult.m128i_i32[3];
|
||||
for (uint64_t i = rest; i < n; i++) {
|
||||
result *= i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrinsic.h"
|
||||
#include "StgSharpNative.h"
|
||||
|
||||
INTERNAL int SN_DECL city_hash_simplify_sse(byte const *str, int const length)
|
||||
{
|
||||
uint32_t hash = length, size = length << 1;
|
||||
byte *end = str + size, *ptr = str;
|
||||
|
||||
if (size < 4) {
|
||||
for (; ptr < end; ptr += 2) {
|
||||
hash = _mm_crc32_u16(hash, *ptr);
|
||||
}
|
||||
} else if (size < 16) {
|
||||
byte *last = end - 4;
|
||||
for (; ptr < end; ptr += 4) {
|
||||
hash = _mm_crc32_u32(hash, *(uint32_t *)ptr);
|
||||
}
|
||||
for (; ptr < end; ptr++) {
|
||||
hash = _mm_crc32_u16(hash, *ptr);
|
||||
}
|
||||
} else {
|
||||
byte *last_128 = end - 16;
|
||||
byte *last_32 = end - 4;
|
||||
uint64_t hash64 = size;
|
||||
for (; ptr < last_128; ptr += 16) {
|
||||
__m128i vec = _mm_loadu_si32((int *)ptr);
|
||||
hash64 = _mm_crc32_u64(hash64, _mm_extract_epi64(vec, 0));
|
||||
hash64 = _mm_crc32_u64(hash64, _mm_extract_epi64(vec, 1));
|
||||
}
|
||||
hash = _mm_crc32_u8(hash, hash64);
|
||||
hash = _mm_crc32_u8(hash, hash64 >> 32);
|
||||
for (; ptr < last_32; ptr += 4) {
|
||||
hash = _mm_crc32_u32(hash, *(uint32_t *)ptr);
|
||||
}
|
||||
for (; ptr < end; ptr += 2) {
|
||||
hash = _mm_crc32_u8(hash, *ptr);
|
||||
}
|
||||
}
|
||||
hash ^= hash >> 16;
|
||||
hash *= 0x85ebca6b;
|
||||
hash ^= hash >> 13;
|
||||
hash *= 0xc2b2ae35;
|
||||
hash ^= hash >> 16;
|
||||
return hash;
|
||||
}
|
||||
|
||||
#endif
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrinsic.h"
|
||||
#include "StgSharpNative.h"
|
||||
|
||||
INTERNAL int SN_DECL city_hash_simplify_sse(byte const *str, int const length)
|
||||
{
|
||||
uint32_t hash = length, size = length << 1;
|
||||
byte *end = str + size, *ptr = str;
|
||||
|
||||
if (size < 4) {
|
||||
for (; ptr < end; ptr += 2) {
|
||||
hash = _mm_crc32_u16(hash, *ptr);
|
||||
}
|
||||
} else if (size < 16) {
|
||||
byte *last = end - 4;
|
||||
for (; ptr < end; ptr += 4) {
|
||||
hash = _mm_crc32_u32(hash, *(uint32_t *)ptr);
|
||||
}
|
||||
for (; ptr < end; ptr++) {
|
||||
hash = _mm_crc32_u16(hash, *ptr);
|
||||
}
|
||||
} else {
|
||||
byte *last_128 = end - 16;
|
||||
byte *last_32 = end - 4;
|
||||
uint64_t hash64 = size;
|
||||
for (; ptr < last_128; ptr += 16) {
|
||||
__m128i vec = _mm_loadu_si32((int *)ptr);
|
||||
hash64 = _mm_crc32_u64(hash64, _mm_extract_epi64(vec, 0));
|
||||
hash64 = _mm_crc32_u64(hash64, _mm_extract_epi64(vec, 1));
|
||||
}
|
||||
hash = _mm_crc32_u8(hash, hash64);
|
||||
hash = _mm_crc32_u8(hash, hash64 >> 32);
|
||||
for (; ptr < last_32; ptr += 4) {
|
||||
hash = _mm_crc32_u32(hash, *(uint32_t *)ptr);
|
||||
}
|
||||
for (; ptr < end; ptr += 2) {
|
||||
hash = _mm_crc32_u8(hash, *ptr);
|
||||
}
|
||||
}
|
||||
hash ^= hash >> 16;
|
||||
hash *= 0x85ebca6b;
|
||||
hash ^= hash >> 13;
|
||||
hash *= 0xc2b2ae35;
|
||||
hash ^= hash >> 16;
|
||||
return hash;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,77 +1,77 @@
|
||||
#ifndef STB_IMAGE_IMPLEMENTATION
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#endif
|
||||
#include "StgSharpNative.h"
|
||||
#include "gl.h"
|
||||
#include "../lib/glfw/glfw3.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
extern GladGLContext *currentContext;
|
||||
extern char infolog[512];
|
||||
|
||||
SN_API int SN_DECL glCheckShaderStat(GladGLContext *context, uint64_t shaderHandle, int key,
|
||||
char **logRef)
|
||||
{
|
||||
int stat = 0;
|
||||
context->GetShaderiv(shaderHandle, key, &stat);
|
||||
if (!stat) {
|
||||
context->GetShaderInfoLog(shaderHandle, 512, NULL, infolog);
|
||||
}
|
||||
*logRef = infolog;
|
||||
return stat;
|
||||
}
|
||||
|
||||
SN_API void SN_DECL initGL(int majorVersion, int minorVersion)
|
||||
{
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, majorVersion);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, minorVersion);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||
}
|
||||
|
||||
SN_API GLFWglproc SN_DECL loadGlfuncDefault(char const *procName)
|
||||
{
|
||||
void *ret = glfwGetProcAddress(procName);
|
||||
// printf("%llu\n", (uint64_t)ret);
|
||||
if (ret == NULL) {
|
||||
strcpy_s(infolog, 30, "Failed to load OpenGL api:");
|
||||
for (size_t i = 0; i < sizeof(procName); i++) {
|
||||
infolog[30 + i] = procName[i];
|
||||
}
|
||||
//printf("%s\n", infolog);
|
||||
}
|
||||
return (GLFWglproc)ret;
|
||||
}
|
||||
|
||||
SN_API unsigned int linkShaderProgram(GladGLContext *context, GLuint shaderProgram)
|
||||
{
|
||||
context->LinkProgram(shaderProgram);
|
||||
|
||||
int success;
|
||||
context->GetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
context->GetProgramInfoLog(shaderProgram, 512, NULL, infolog);
|
||||
return 0;
|
||||
} else {
|
||||
return shaderProgram;
|
||||
}
|
||||
}
|
||||
|
||||
SN_API void SN_DECL loadImageData(char const *location, Image *out, imageLoader loader)
|
||||
{
|
||||
if (loader == NULL) {
|
||||
loader = stbi_load;
|
||||
}
|
||||
out->pixelPtr = loader(location, &(out->width), &(out->height), &(out->channel), 0);
|
||||
}
|
||||
SN_API void SN_DECL unloadImageData(Image *out)
|
||||
{
|
||||
free(out->pixelPtr);
|
||||
}
|
||||
|
||||
SN_API char *SN_DECL readLog()
|
||||
{
|
||||
infolog[511] = '\0';
|
||||
return infolog;
|
||||
}
|
||||
#ifndef STB_IMAGE_IMPLEMENTATION
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#endif
|
||||
#include "StgSharpNative.h"
|
||||
#include "gl.h"
|
||||
#include "../lib/glfw/glfw3.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
extern GladGLContext *currentContext;
|
||||
extern char infolog[512];
|
||||
|
||||
SN_API int SN_DECL glCheckShaderStat(GladGLContext *context, uint64_t shaderHandle, int key,
|
||||
char **logRef)
|
||||
{
|
||||
int stat = 0;
|
||||
context->GetShaderiv(shaderHandle, key, &stat);
|
||||
if (!stat) {
|
||||
context->GetShaderInfoLog(shaderHandle, 512, NULL, infolog);
|
||||
}
|
||||
*logRef = infolog;
|
||||
return stat;
|
||||
}
|
||||
|
||||
SN_API void SN_DECL initGL(int majorVersion, int minorVersion)
|
||||
{
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, majorVersion);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, minorVersion);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||
}
|
||||
|
||||
SN_API GLFWglproc SN_DECL loadGlfuncDefault(char const *procName)
|
||||
{
|
||||
void *ret = glfwGetProcAddress(procName);
|
||||
// printf("%llu\n", (uint64_t)ret);
|
||||
if (ret == NULL) {
|
||||
strcpy_s(infolog, 30, "Failed to load OpenGL api:");
|
||||
for (size_t i = 0; i < sizeof(procName); i++) {
|
||||
infolog[30 + i] = procName[i];
|
||||
}
|
||||
//printf("%s\n", infolog);
|
||||
}
|
||||
return (GLFWglproc)ret;
|
||||
}
|
||||
|
||||
SN_API unsigned int linkShaderProgram(GladGLContext *context, GLuint shaderProgram)
|
||||
{
|
||||
context->LinkProgram(shaderProgram);
|
||||
|
||||
int success;
|
||||
context->GetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
context->GetProgramInfoLog(shaderProgram, 512, NULL, infolog);
|
||||
return 0;
|
||||
} else {
|
||||
return shaderProgram;
|
||||
}
|
||||
}
|
||||
|
||||
SN_API void SN_DECL loadImageData(char const *location, Image *out, imageLoader loader)
|
||||
{
|
||||
if (loader == NULL) {
|
||||
loader = stbi_load;
|
||||
}
|
||||
out->pixelPtr = loader(location, &(out->width), &(out->height), &(out->channel), 0);
|
||||
}
|
||||
SN_API void SN_DECL unloadImageData(Image *out)
|
||||
{
|
||||
free(out->pixelPtr);
|
||||
}
|
||||
|
||||
SN_API char *SN_DECL readLog()
|
||||
{
|
||||
infolog[511] = '\0';
|
||||
return infolog;
|
||||
}
|
||||
|
||||
@@ -1,54 +1,54 @@
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrinsic.h"
|
||||
|
||||
INTERNAL int SN_DECL index_pair_sse(short const *str, uint32_t target, int length)
|
||||
{
|
||||
int index = 0, result = 0, size = length, end = size - 8;
|
||||
__m128i s = _mm_set1_epi32(target);
|
||||
__m128i vec, com;
|
||||
|
||||
while (index < end) {
|
||||
vec = _mm_loadu_epi32(str + index);
|
||||
com = _mm_cmpeq_epi16(vec, s);
|
||||
result = _mm_movemask_epi8(com);
|
||||
if (result) {
|
||||
for (size_t i = 0; i < 7; i++) {
|
||||
if (((result & 0xF) == 0xF)) {
|
||||
return index + i;
|
||||
}
|
||||
if (result == 0) {
|
||||
break;
|
||||
}
|
||||
result >>= 2;
|
||||
}
|
||||
}
|
||||
index += 1;
|
||||
vec = _mm_loadu_epi32(str + index);
|
||||
com = _mm_cmpeq_epi16(vec, s);
|
||||
result = _mm_movemask_epi8(com);
|
||||
if (result) {
|
||||
for (size_t i = 0; i < 7; i++) {
|
||||
if (((result & 0xF) == 0xF)) {
|
||||
return index + i;
|
||||
}
|
||||
if (result == 0) {
|
||||
break;
|
||||
}
|
||||
result >>= 2;
|
||||
}
|
||||
}
|
||||
index += 7;
|
||||
}
|
||||
for (; (index < size - 1) && (!result); index += 2) {
|
||||
result = *(int *)(str + index) == target;
|
||||
}
|
||||
if (result) {
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
#include "sn_target.h"
|
||||
|
||||
#if SN_IS_ARCH(SN_ARCH_X86_64)
|
||||
|
||||
#include "sn_intrinsic.h"
|
||||
|
||||
INTERNAL int SN_DECL index_pair_sse(short const *str, uint32_t target, int length)
|
||||
{
|
||||
int index = 0, result = 0, size = length, end = size - 8;
|
||||
__m128i s = _mm_set1_epi32(target);
|
||||
__m128i vec, com;
|
||||
|
||||
while (index < end) {
|
||||
vec = _mm_loadu_epi32(str + index);
|
||||
com = _mm_cmpeq_epi16(vec, s);
|
||||
result = _mm_movemask_epi8(com);
|
||||
if (result) {
|
||||
for (size_t i = 0; i < 7; i++) {
|
||||
if (((result & 0xF) == 0xF)) {
|
||||
return index + i;
|
||||
}
|
||||
if (result == 0) {
|
||||
break;
|
||||
}
|
||||
result >>= 2;
|
||||
}
|
||||
}
|
||||
index += 1;
|
||||
vec = _mm_loadu_epi32(str + index);
|
||||
com = _mm_cmpeq_epi16(vec, s);
|
||||
result = _mm_movemask_epi8(com);
|
||||
if (result) {
|
||||
for (size_t i = 0; i < 7; i++) {
|
||||
if (((result & 0xF) == 0xF)) {
|
||||
return index + i;
|
||||
}
|
||||
if (result == 0) {
|
||||
break;
|
||||
}
|
||||
result >>= 2;
|
||||
}
|
||||
}
|
||||
index += 7;
|
||||
}
|
||||
for (; (index < size - 1) && (!result); index += 2) {
|
||||
result = *(int *)(str + index) == target;
|
||||
}
|
||||
if (result) {
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
#include "sn_intrinsic.h"
|
||||
#include "sn_internal.h"
|
||||
|
||||
INTERNAL void SN_DECL f32_normalize(VEC(float) *restrict source, VEC(float) *restrict target)
|
||||
{
|
||||
register __m128 s = _mm_load_ps(&source->f32_x);
|
||||
register __m128 a_length_sq = _mm_mul_ps(s, s);
|
||||
a_length_sq = _mm_add_ps(a_length_sq,
|
||||
_mm_shuffle_ps(a_length_sq, a_length_sq, _MM_SHUFFLE(2, 3, 0, 1)));
|
||||
a_length_sq = _mm_add_ss(a_length_sq,
|
||||
_mm_shuffle_ps(a_length_sq, a_length_sq, _MM_SHUFFLE(0, 0, 3, 2)));
|
||||
|
||||
__m128 a_inv_length = _mm_rsqrt_ps(a_length_sq);
|
||||
s = _mm_mul_ps(s, a_inv_length);
|
||||
|
||||
__m128 dot_product = _mm_mul_ps(target->f32_x[0], s);
|
||||
dot_product = _mm_add_ps(dot_product,
|
||||
_mm_shuffle_ps(dot_product, dot_product, _MM_SHUFFLE(2, 3, 0, 1)));
|
||||
dot_product = _mm_add_ss(dot_product,
|
||||
_mm_shuffle_ps(dot_product, dot_product, _MM_SHUFFLE(0, 0, 3, 2)));
|
||||
|
||||
__m128 b_orthogonal = _mm_sub_ps(target->f32_x[0], _mm_mul_ps(s, dot_product));
|
||||
|
||||
__m128 b_length_sq = _mm_mul_ps(b_orthogonal, b_orthogonal);
|
||||
b_length_sq = _mm_add_ps(b_length_sq,
|
||||
_mm_shuffle_ps(b_length_sq, b_length_sq, _MM_SHUFFLE(2, 3, 0, 1)));
|
||||
b_length_sq = _mm_add_ss(b_length_sq,
|
||||
_mm_shuffle_ps(b_length_sq, b_length_sq, _MM_SHUFFLE(0, 0, 3, 2)));
|
||||
|
||||
__m128 b_inv_length = _mm_rsqrt_ps(b_length_sq);
|
||||
target->f32_x[0] = _mm_mul_ps(b_orthogonal, b_inv_length);
|
||||
}
|
||||
#include "sn_intrinsic.h"
|
||||
#include "sn_internal.h"
|
||||
|
||||
INTERNAL void SN_DECL f32_normalize(VEC(float) *restrict source, VEC(float) *restrict target)
|
||||
{
|
||||
register __m128 s = _mm_load_ps(&source->f32_x);
|
||||
register __m128 a_length_sq = _mm_mul_ps(s, s);
|
||||
a_length_sq = _mm_add_ps(a_length_sq,
|
||||
_mm_shuffle_ps(a_length_sq, a_length_sq, _MM_SHUFFLE(2, 3, 0, 1)));
|
||||
a_length_sq = _mm_add_ss(a_length_sq,
|
||||
_mm_shuffle_ps(a_length_sq, a_length_sq, _MM_SHUFFLE(0, 0, 3, 2)));
|
||||
|
||||
__m128 a_inv_length = _mm_rsqrt_ps(a_length_sq);
|
||||
s = _mm_mul_ps(s, a_inv_length);
|
||||
|
||||
__m128 dot_product = _mm_mul_ps(target->f32_x[0], s);
|
||||
dot_product = _mm_add_ps(dot_product,
|
||||
_mm_shuffle_ps(dot_product, dot_product, _MM_SHUFFLE(2, 3, 0, 1)));
|
||||
dot_product = _mm_add_ss(dot_product,
|
||||
_mm_shuffle_ps(dot_product, dot_product, _MM_SHUFFLE(0, 0, 3, 2)));
|
||||
|
||||
__m128 b_orthogonal = _mm_sub_ps(target->f32_x[0], _mm_mul_ps(s, dot_product));
|
||||
|
||||
__m128 b_length_sq = _mm_mul_ps(b_orthogonal, b_orthogonal);
|
||||
b_length_sq = _mm_add_ps(b_length_sq,
|
||||
_mm_shuffle_ps(b_length_sq, b_length_sq, _MM_SHUFFLE(2, 3, 0, 1)));
|
||||
b_length_sq = _mm_add_ss(b_length_sq,
|
||||
_mm_shuffle_ps(b_length_sq, b_length_sq, _MM_SHUFFLE(0, 0, 3, 2)));
|
||||
|
||||
__m128 b_inv_length = _mm_rsqrt_ps(b_length_sq);
|
||||
target->f32_x[0] = _mm_mul_ps(b_orthogonal, b_inv_length);
|
||||
}
|
||||
|
||||
@@ -1,67 +1,67 @@
|
||||
#include "sn_intrinsic.h"
|
||||
#include "sn_internal.h"
|
||||
|
||||
static const int avxdot_indices[] = { 0, 4, 1, 5, 2, 3, 6, 7 };
|
||||
|
||||
INTERNAL void FORCEINLINE SN_DECL dot_41_sse(MAT_KERNEL(float) const *transpose,
|
||||
__m128 const *vector, __m128 *ans)
|
||||
{
|
||||
*ans = _mm_dp_ps(transpose->f32_x[0], *vector, 0B11110001);
|
||||
*ans = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[1], *vector, 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 1));
|
||||
*ans = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[2], *vector, 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 3));
|
||||
*ans = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[3], *vector, 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 4));
|
||||
}
|
||||
|
||||
INTERNAL void SN_DECL dot_41_avx(MAT_KERNEL(float) const *transpose, __m128 const *vector,
|
||||
__m128 *ans)
|
||||
{
|
||||
__m256 _double = _mm256_set_m128(vector[0], vector[0]);
|
||||
__m256 tmp = _mm256_dp_ps(transpose->f32_y[0], _double, 0B11110001);
|
||||
tmp = _mm256_blend_ps(tmp, _mm256_dp_ps(transpose->f32_y[0], _double, 0B11110010),
|
||||
0B00100010);
|
||||
*ans = _mm256_castps256_ps128(
|
||||
_mm256_permutevar8x32_ps(tmp, _mm256_loadu_epi32(avxdot_indices)));
|
||||
}
|
||||
|
||||
INTERNAL void SN_DECL dot_42_sse(MAT_KERNEL(float) const *transpose, __m128 const *vector,
|
||||
__m128 *ans)
|
||||
{
|
||||
ans[0] = _mm_dp_ps(transpose->f32_x[0], vector[0], 0B11110001);
|
||||
ans[0] = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[1], vector[0], 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 2));
|
||||
ans[0] = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[2], vector[0], 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 3));
|
||||
ans[0] = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[3], vector[0], 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 4));
|
||||
|
||||
ans[1] = _mm_dp_ps(transpose->f32_x[0], vector[1], 0B11110001);
|
||||
ans[1] = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[1], vector[1], 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 2));
|
||||
ans[1] = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[2], vector[1], 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 3));
|
||||
ans[1] = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[3], vector[1], 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 4));
|
||||
}
|
||||
|
||||
INTERNAL void SN_DECL dot_42_avx(MAT_KERNEL(float) const *transpose, __m128 const *vector,
|
||||
__m128 *ans)
|
||||
{
|
||||
__m256 temp = transpose->f32_y[0];
|
||||
__m256 vector_stream = _mm256_set_m128(vector[1], vector[0]);
|
||||
|
||||
__m256 result = _mm256_dp_ps(temp, vector_stream, 0B11110001);
|
||||
temp = _mm256_permute2f128_ps(temp, temp, 0B00000001);
|
||||
result = _mm256_blend_ps(result, _mm256_dp_ps(temp, vector_stream, 0B11110010), 0B00100010);
|
||||
|
||||
temp = transpose->f32_y[1];
|
||||
result = _mm256_blend_ps(result, _mm256_dp_ps(temp, vector_stream, 0B11110100), 0B01000100);
|
||||
temp = _mm256_permute2f128_ps(temp, temp, 0B00000001);
|
||||
result = _mm256_blend_ps(result, _mm256_dp_ps(temp, vector_stream, 0B11111000), 0B10001000);
|
||||
|
||||
ans[0] = _mm256_castps256_ps128(result);
|
||||
ans[1] = _mm256_extractf128_ps(result, 1);
|
||||
ans[1] = _mm_shuffle_ps(ans[1], ans[1], _MM_SHUFFLE(2, 3, 0, 1));
|
||||
}
|
||||
#include "sn_intrinsic.h"
|
||||
#include "sn_internal.h"
|
||||
|
||||
static const int avxdot_indices[] = { 0, 4, 1, 5, 2, 3, 6, 7 };
|
||||
|
||||
INTERNAL void FORCEINLINE SN_DECL dot_41_sse(MAT_KERNEL(float) const *transpose,
|
||||
__m128 const *vector, __m128 *ans)
|
||||
{
|
||||
*ans = _mm_dp_ps(transpose->f32_x[0], *vector, 0B11110001);
|
||||
*ans = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[1], *vector, 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 1));
|
||||
*ans = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[2], *vector, 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 3));
|
||||
*ans = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[3], *vector, 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 4));
|
||||
}
|
||||
|
||||
INTERNAL void SN_DECL dot_41_avx(MAT_KERNEL(float) const *transpose, __m128 const *vector,
|
||||
__m128 *ans)
|
||||
{
|
||||
__m256 _double = _mm256_set_m128(vector[0], vector[0]);
|
||||
__m256 tmp = _mm256_dp_ps(transpose->f32_y[0], _double, 0B11110001);
|
||||
tmp = _mm256_blend_ps(tmp, _mm256_dp_ps(transpose->f32_y[0], _double, 0B11110010),
|
||||
0B00100010);
|
||||
*ans = _mm256_castps256_ps128(
|
||||
_mm256_permutevar8x32_ps(tmp, _mm256_loadu_epi32(avxdot_indices)));
|
||||
}
|
||||
|
||||
INTERNAL void SN_DECL dot_42_sse(MAT_KERNEL(float) const *transpose, __m128 const *vector,
|
||||
__m128 *ans)
|
||||
{
|
||||
ans[0] = _mm_dp_ps(transpose->f32_x[0], vector[0], 0B11110001);
|
||||
ans[0] = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[1], vector[0], 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 2));
|
||||
ans[0] = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[2], vector[0], 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 3));
|
||||
ans[0] = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[3], vector[0], 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 4));
|
||||
|
||||
ans[1] = _mm_dp_ps(transpose->f32_x[0], vector[1], 0B11110001);
|
||||
ans[1] = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[1], vector[1], 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 2));
|
||||
ans[1] = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[2], vector[1], 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 3));
|
||||
ans[1] = _mm_insert_ps(*ans, _mm_dp_ps(transpose->f32_x[3], vector[1], 0B11110001),
|
||||
SSE_INSERT_SIMPLE(1, 4));
|
||||
}
|
||||
|
||||
INTERNAL void SN_DECL dot_42_avx(MAT_KERNEL(float) const *transpose, __m128 const *vector,
|
||||
__m128 *ans)
|
||||
{
|
||||
__m256 temp = transpose->f32_y[0];
|
||||
__m256 vector_stream = _mm256_set_m128(vector[1], vector[0]);
|
||||
|
||||
__m256 result = _mm256_dp_ps(temp, vector_stream, 0B11110001);
|
||||
temp = _mm256_permute2f128_ps(temp, temp, 0B00000001);
|
||||
result = _mm256_blend_ps(result, _mm256_dp_ps(temp, vector_stream, 0B11110010), 0B00100010);
|
||||
|
||||
temp = transpose->f32_y[1];
|
||||
result = _mm256_blend_ps(result, _mm256_dp_ps(temp, vector_stream, 0B11110100), 0B01000100);
|
||||
temp = _mm256_permute2f128_ps(temp, temp, 0B00000001);
|
||||
result = _mm256_blend_ps(result, _mm256_dp_ps(temp, vector_stream, 0B11111000), 0B10001000);
|
||||
|
||||
ans[0] = _mm256_castps256_ps128(result);
|
||||
ans[1] = _mm256_extractf128_ps(result, 1);
|
||||
ans[1] = _mm_shuffle_ps(ans[1], ans[1], _MM_SHUFFLE(2, 3, 0, 1));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user