Compare commits
344
Commits
gemm_batch
...
v0.3.31
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76f1be470c | ||
|
|
0e7b11fbc3 | ||
|
|
ca1aefc5f9 | ||
|
|
366847fc10 | ||
|
|
10bd0ec4c3 | ||
|
|
5bb7ef1466 | ||
|
|
4cd575c20f | ||
|
|
6f225daf94 | ||
|
|
55a10c748d | ||
|
|
5133aac055 | ||
|
|
faa18750d6 | ||
|
|
7acf919836 | ||
|
|
93cd7b9238 | ||
|
|
d49df4c579 | ||
|
|
7ffce1c788 | ||
|
|
88c583ed49 | ||
|
|
d3e4b41136 | ||
|
|
6735872092 | ||
|
|
6137236c0a | ||
|
|
fa021e1887 | ||
|
|
bdcb9b7252 | ||
|
|
533cab235f | ||
|
|
31bb6ca7df | ||
|
|
5e5f9a39ad | ||
|
|
770ad6883d | ||
|
|
10ba0e6044 | ||
|
|
3149408165 | ||
|
|
e07bea17c8 | ||
|
|
e04df1941d | ||
|
|
31150eb1e6 | ||
|
|
0a53d91789 | ||
|
|
aafd3cb0db | ||
|
|
01cc6df92e | ||
|
|
e776297bf9 | ||
|
|
05d7c18894 | ||
|
|
4d08156266 | ||
|
|
6de062cfc2 | ||
|
|
52ec7faf31 | ||
|
|
1ffea2b8c1 | ||
|
|
d1de282a4e | ||
|
|
e5aebeaf93 | ||
|
|
a514760e06 | ||
|
|
d7d1088d21 | ||
|
|
a9a6edaf17 | ||
|
|
2d46f1ec65 | ||
|
|
c040d5ed86 | ||
|
|
6939a43c3b | ||
|
|
20ae36ba75 | ||
|
|
b53d18b3ad | ||
|
|
7e612b640f | ||
|
|
e384396a51 | ||
|
|
02bc005306 | ||
|
|
a18a53605e | ||
|
|
618bcbd7c0 | ||
|
|
badf4c09e2 | ||
|
|
879497990f | ||
|
|
2283fcbbe7 | ||
|
|
67fd33e729 | ||
|
|
f4383d0235 | ||
|
|
7beba94023 | ||
|
|
b183182e61 | ||
|
|
5c8cf37d83 | ||
|
|
275eb6f7f3 | ||
|
|
e4344def6a | ||
|
|
80951a2acc | ||
|
|
772741e2b1 | ||
|
|
54f7b76f20 | ||
|
|
579eda3778 | ||
|
|
83a788c387 | ||
|
|
5e3a9922bd | ||
|
|
e548bda1ba | ||
|
|
cd02751b12 | ||
|
|
5766adbcad | ||
|
|
1f2bffb4fe | ||
|
|
067e43c1e1 | ||
|
|
0ff51a40f1 | ||
|
|
0b2b583223 | ||
|
|
fed16d638c | ||
|
|
d39b77748f | ||
|
|
371663f0c2 | ||
|
|
097d2d98fd | ||
|
|
5b0884d8e7 | ||
|
|
c7b0304ba3 | ||
|
|
652bf6b51b | ||
|
|
9fa64b9a3d | ||
|
|
b8163b65cb | ||
|
|
ac2c66321d | ||
|
|
cfa28bcf71 | ||
|
|
6bc4276f90 | ||
|
|
bc52252cd5 | ||
|
|
5aff62eb96 | ||
|
|
e155bc0061 | ||
|
|
e1d2411545 | ||
|
|
cbecf98308 | ||
|
|
eb098f67d3 | ||
|
|
9023e76a77 | ||
|
|
486d150662 | ||
|
|
4dbbdcaeb4 | ||
|
|
5d68b8fc58 | ||
|
|
a680c60a69 | ||
|
|
e7ddd63234 | ||
|
|
38882e0123 | ||
|
|
231d7c4397 | ||
|
|
80a12ae824 | ||
|
|
938477683f | ||
|
|
e85efb8d86 | ||
|
|
68ff451ecc | ||
|
|
f6533ccea0 | ||
|
|
396137ff27 | ||
|
|
7750d507ff | ||
|
|
825d3ad12e | ||
|
|
5f0735832b | ||
|
|
c3c857c95e | ||
|
|
7ab8dc125d | ||
|
|
705259c344 | ||
|
|
a683287006 | ||
|
|
b185c9a4ce | ||
|
|
4af187080a | ||
|
|
b0bd49a064 | ||
|
|
7e44f62a09 | ||
|
|
8da0a1fb9c | ||
|
|
7d35bf61ba | ||
|
|
8c0b13c41c | ||
|
|
d6b25c43c6 | ||
|
|
5b79d01424 | ||
|
|
9c0965b884 | ||
|
|
48e33f23e8 | ||
|
|
7cef9524f7 | ||
|
|
88c1899b88 | ||
|
|
ea85b6696f | ||
|
|
0d5bf7b760 | ||
|
|
93d0d195a0 | ||
|
|
c5e1967ddb | ||
|
|
58ee3c0761 | ||
|
|
4867c421ed | ||
|
|
fa0403bd17 | ||
|
|
29fab2b912 | ||
|
|
f7b7296bff | ||
|
|
a367f5f58b | ||
|
|
64b9600724 | ||
|
|
a14caf464f | ||
|
|
28eeef5bbe | ||
|
|
a51a1b8e1f | ||
|
|
17f2e94260 | ||
|
|
75ceb6c69f | ||
|
|
ccef6ccde7 | ||
|
|
762ed66c72 | ||
|
|
98a8230dee | ||
|
|
39d5e44723 | ||
|
|
71c6016206 | ||
|
|
f6df9bebbb | ||
|
|
aa7e9abf52 | ||
|
|
bbb87aa5c2 | ||
|
|
f00c0d0827 | ||
|
|
8a0b97e0d3 | ||
|
|
f2d010de12 | ||
|
|
65af1b1401 | ||
|
|
7bdb3ac720 | ||
|
|
123c25c748 | ||
|
|
00a7336fc9 | ||
|
|
edf2e5900c | ||
|
|
7ca689b54f | ||
|
|
8882409131 | ||
|
|
3a9da520d5 | ||
|
|
93e89c09be | ||
|
|
92fe96b460 | ||
|
|
9c8626d73a | ||
|
|
2e7c667c11 | ||
|
|
2b745f816d | ||
|
|
716feb6704 | ||
|
|
aa43496936 | ||
|
|
358c582ef9 | ||
|
|
1da3b47163 | ||
|
|
18eb6a7f70 | ||
|
|
ef6f97624b | ||
|
|
0c59ae0b45 | ||
|
|
c1c1285236 | ||
|
|
8e44cde3f6 | ||
|
|
75b3e110c4 | ||
|
|
c5b0d1efd1 | ||
|
|
585e6d0680 | ||
|
|
677424ad55 | ||
|
|
43d0803949 | ||
|
|
b2b9abc20b | ||
|
|
cb66aca707 | ||
|
|
3d19d3b60a | ||
|
|
43d38d336f | ||
|
|
682f61e8b8 | ||
|
|
83d3e0ed1a | ||
|
|
1b591ea4ed | ||
|
|
f4ee3aec88 | ||
|
|
e01b1094de | ||
|
|
643a0b53b0 | ||
|
|
d7b0fccbb4 | ||
|
|
2346d0bdc4 | ||
|
|
8211db6203 | ||
|
|
aef36a3ff0 | ||
|
|
016e2f14e2 | ||
|
|
4c1741d814 | ||
|
|
c35b11a86b | ||
|
|
098a8d5865 | ||
|
|
f3cecbebe7 | ||
|
|
5b640b1cbc | ||
|
|
a9a152ebc7 | ||
|
|
a387217a07 | ||
|
|
c92bac1524 | ||
|
|
c0b2772288 | ||
|
|
ee6aa89fb0 | ||
|
|
3d5010bf37 | ||
|
|
887f4f32ed | ||
|
|
19be504cd0 | ||
|
|
96f34621fb | ||
|
|
05adb52353 | ||
|
|
6637352260 | ||
|
|
87470a3b18 | ||
|
|
d539685c49 | ||
|
|
9bfc3612f9 | ||
|
|
b6d5057493 | ||
|
|
b94e9b92ad | ||
|
|
e40714cabd | ||
|
|
ffd2e47995 | ||
|
|
a5fda2e2c3 | ||
|
|
cb48a52d42 | ||
|
|
476677568b | ||
|
|
5ba2b9e138 | ||
|
|
5b18a3f08a | ||
|
|
e9a4553a1a | ||
|
|
fba2014239 | ||
|
|
d5870f2628 | ||
|
|
5c89e4c770 | ||
|
|
4291fa2f7a | ||
|
|
09c18779bb | ||
|
|
644ea07ef9 | ||
|
|
f6b0d48a39 | ||
|
|
de004136cd | ||
|
|
acff97cef1 | ||
|
|
e2399be6d2 | ||
|
|
6f3691a84b | ||
|
|
4ac29b9a77 | ||
|
|
03a83778bb | ||
|
|
ac1604b40c | ||
|
|
47a66aef0f | ||
|
|
20f5ed1a94 | ||
|
|
c3ce473ab2 | ||
|
|
49eca84eaf | ||
|
|
fa912ce852 | ||
|
|
7af2225354 | ||
|
|
46fc6c0794 | ||
|
|
064751ee65 | ||
|
|
ba143f3288 | ||
|
|
de43ccc566 | ||
|
|
f552040c5d | ||
|
|
37fc3bbca0 | ||
|
|
8918247207 | ||
|
|
106fabcd40 | ||
|
|
aecb7f9537 | ||
|
|
db9e7ac224 | ||
|
|
958f721e36 | ||
|
|
578e7dae85 | ||
|
|
809e1cba8f | ||
|
|
e07a9ae418 | ||
|
|
1eafda12ad | ||
|
|
588f0e87cc | ||
|
|
c889558317 | ||
|
|
4ae3e37b45 | ||
|
|
b3d0bc40e9 | ||
|
|
ba9d2d29f3 | ||
|
|
b48a089d75 | ||
|
|
fc516af155 | ||
|
|
e939c6c315 | ||
|
|
03c8d1010f | ||
|
|
3eed1883cd | ||
|
|
36f9cb85b1 | ||
|
|
2d82d144e2 | ||
|
|
dd7a1d6d4d | ||
|
|
b7c8c5c190 | ||
|
|
aaa5c377bc | ||
|
|
c1f607c43c | ||
|
|
19268471cc | ||
|
|
1dcd4cb6e9 | ||
|
|
67ddda394e | ||
|
|
d7b11605d1 | ||
|
|
b27a1184fd | ||
|
|
4ef70b490c | ||
|
|
b537dacb34 | ||
|
|
f5ec1c4e53 | ||
|
|
681af71d95 | ||
|
|
07d0e742c2 | ||
|
|
e58f6dc50d | ||
|
|
c92f7f6bb2 | ||
|
|
65c626e646 | ||
|
|
f2304af1d3 | ||
|
|
2852171d4f | ||
|
|
916a47409c | ||
|
|
14c9dcaac7 | ||
|
|
6798aec462 | ||
|
|
7989caabdc | ||
|
|
fc7d6e65a1 | ||
|
|
9427eaf4c4 | ||
|
|
3116749717 | ||
|
|
fe5402d82b | ||
|
|
5a8f9aa8fc | ||
|
|
92f09a6a98 | ||
|
|
16be28af7c | ||
|
|
e5c836136d | ||
|
|
a4abf7828e | ||
|
|
1d5279fd29 | ||
|
|
ed6c223105 | ||
|
|
fd8f0d4f8c | ||
|
|
2b5d8c789d | ||
|
|
1b88c9c742 | ||
|
|
b4fc09e9e1 | ||
|
|
8e50b8d525 | ||
|
|
7f89c6f353 | ||
|
|
1ee8879c78 | ||
|
|
edaa73fd24 | ||
|
|
501728a354 | ||
|
|
107c883c8a | ||
|
|
05dbb54362 | ||
|
|
4609732e69 | ||
|
|
bf98e448eb | ||
|
|
0bc19a1335 | ||
|
|
426b5f23ed | ||
|
|
4328c91e27 | ||
|
|
c794d0a4ce | ||
|
|
a4f5fec46e | ||
|
|
ca542f319f | ||
|
|
18f9582f3e | ||
|
|
4e2a8c18e5 | ||
|
|
30970460b8 | ||
|
|
b0a00fbd62 | ||
|
|
ccfd0170fb | ||
|
|
ef0b883dff | ||
|
|
e76c39099a | ||
|
|
202a7a0e2a | ||
|
|
de91afd2ae | ||
|
|
0203657f40 | ||
|
|
e82bcd2740 | ||
|
|
731f4dd686 | ||
|
|
53d3bb50cc | ||
|
|
08a00326a4 | ||
|
|
89898fc499 | ||
|
|
22c6607db9 | ||
|
|
ca22e28ca1 |
+7
-7
@@ -58,8 +58,8 @@ task:
|
||||
- export VALID_ARCHS="i386 x86_64"
|
||||
- xcrun --sdk macosx --show-sdk-path
|
||||
- xcodebuild -version
|
||||
- export CC=/Applications/Xcode_16.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
|
||||
- export CFLAGS="-O2 -unwindlib=none -Wno-macro-redefined -isysroot /Applications/Xcode_16.3.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.4.sdk -arch x86_64"
|
||||
- export CC=/Applications/Xcode_26.0.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
|
||||
- export CFLAGS="-O2 -unwindlib=none -Wno-macro-redefined -isysroot /Applications/Xcode_26.0.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.0.sdk -arch x86_64"
|
||||
- make TARGET=CORE2 DYNAMIC_ARCH=1 NUM_THREADS=32 HOSTCC=clang NOFORTRAN=1 RANLIB="ls -l"
|
||||
always:
|
||||
config_artifacts:
|
||||
@@ -78,8 +78,8 @@ task:
|
||||
- export #PATH=/opt/homebrew/opt/llvm/bin:$PATH
|
||||
- export #LDFLAGS="-L/opt/homebrew/opt/llvm/lib"
|
||||
- export #CPPFLAGS="-I/opt/homebrew/opt/llvm/include"
|
||||
- export CC=/Applications/Xcode_16.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
|
||||
- export CFLAGS="-O2 -unwindlib=none -Wno-macro-redefined -isysroot /Applications/Xcode_16.3.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.4.sdk -arch arm64 -miphoneos-version-min=10.0"
|
||||
- export CC=/Applications/Xcode_26.0.1.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
|
||||
- export CFLAGS="-O2 -unwindlib=none -Wno-macro-redefined -isysroot /Applications/Xcode_26.0.1.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS26.0.sdk -arch arm64 -miphoneos-version-min=10.0"
|
||||
- xcrun --sdk iphoneos --show-sdk-path
|
||||
- ls -l /Applications
|
||||
- make TARGET=ARMV8 NUM_THREADS=32 HOSTCC=clang NOFORTRAN=1 CROSS=1
|
||||
@@ -127,7 +127,7 @@ task:
|
||||
FreeBSD_task:
|
||||
name: FreeBSD-gcc
|
||||
freebsd_instance:
|
||||
image_family: freebsd-14-2
|
||||
image_family: freebsd-14-3
|
||||
install_script:
|
||||
- pkg update -f && pkg upgrade -y && pkg install -y gmake gcc
|
||||
compile_script:
|
||||
@@ -138,7 +138,7 @@ FreeBSD_task:
|
||||
FreeBSD_task:
|
||||
name: freebsd-gcc-ilp64
|
||||
freebsd_instance:
|
||||
image_family: freebsd-14-2
|
||||
image_family: freebsd-14-3
|
||||
install_script:
|
||||
- pkg update -f && pkg upgrade -y && pkg install -y gmake gcc
|
||||
compile_script:
|
||||
@@ -148,7 +148,7 @@ FreeBSD_task:
|
||||
FreeBSD_task:
|
||||
name: FreeBSD-clang-openmp
|
||||
freebsd_instance:
|
||||
image_family: freebsd-14-2
|
||||
image_family: freebsd-14-3
|
||||
install_script:
|
||||
- pkg update -f && pkg upgrade -y && pkg install -y gmake gcc
|
||||
- ln -s /usr/local/lib/gcc13/libgfortran.so.5.0.0 /usr/lib/libgfortran.so
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: continuous build
|
||||
|
||||
on: [push, pull_request]
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
|
||||
@@ -11,17 +11,24 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
if: "github.repository == 'OpenMathLib/OpenBLAS'"
|
||||
if: "github.repository == 'OpenMathLib/OpenBLAS' || github.event_name == 'workflow_dispatch'"
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
os: [ubuntu-latest, macos-latest, ubuntu-24.04-arm]
|
||||
cc: [gcc, clang, clang-21]
|
||||
fortran: [gfortran, flang]
|
||||
build: [cmake, make]
|
||||
exclude:
|
||||
- os: macos-latest
|
||||
cc: gcc
|
||||
- os: macos-latest
|
||||
cc: clang-21
|
||||
- os: macos-latest
|
||||
fortran: flang
|
||||
- os: ubuntu-24.04-arm
|
||||
fortran: flang
|
||||
|
||||
steps:
|
||||
@@ -42,10 +49,23 @@ jobs:
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||
cat << EOF | sudo tee -a /etc/apt/apt.conf.d/01norecommend
|
||||
APT::Install-Recommends "0";
|
||||
APT::Install-Suggests "0";
|
||||
EOF
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y gfortran cmake ccache
|
||||
wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb
|
||||
sudo apt install ./libtinfo5_6.3-2ubuntu0.1_amd64.deb
|
||||
sudo apt-get install -y ccache
|
||||
if [ "${{ matrix.cc }}" == "clang-21" ]; then
|
||||
wget https://apt.llvm.org/llvm.sh
|
||||
chmod +x llvm.sh
|
||||
sudo ./llvm.sh 21
|
||||
fi
|
||||
if [ "${{ matrix.fortran }}" == "flang" ]; then
|
||||
wget http://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb
|
||||
sudo apt install ./libtinfo5_6.3-2ubuntu0.1_amd64.deb
|
||||
else
|
||||
sudo apt-get install -y ${{ matrix.fortran }}
|
||||
fi
|
||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||
# It looks like "gfortran" isn't working correctly unless "gcc" is re-installed.
|
||||
brew reinstall gcc
|
||||
@@ -64,12 +84,12 @@ jobs:
|
||||
# GNU make and cmake call the compilers differently. It looks like
|
||||
# that causes the cache to mismatch. Keep the ccache for both build
|
||||
# tools separate to avoid polluting each other.
|
||||
key: ccache-${{ runner.os }}-${{ matrix.build }}-${{ matrix.fortran }}-${{ github.ref }}-${{ github.sha }}
|
||||
key: ccache-${{ runner.os }}-${{ runner.arch }}-${{ matrix.build }}-${{ matrix.cc }}-${{ matrix.fortran }}-${{ github.ref }}-${{ github.sha }}
|
||||
# Restore a matching ccache cache entry. Prefer same branch and same Fortran compiler.
|
||||
restore-keys: |
|
||||
ccache-${{ runner.os }}-${{ matrix.build }}-${{ matrix.fortran }}-${{ github.ref }}
|
||||
ccache-${{ runner.os }}-${{ matrix.build }}-${{ matrix.fortran }}
|
||||
ccache-${{ runner.os }}-${{ matrix.build }}
|
||||
ccache-${{ runner.os }}-${{ runner.arch }}-${{ matrix.build }}-${{ matrix.cc }}-${{ matrix.fortran }}-${{ github.ref }}
|
||||
ccache-${{ runner.os }}-${{ runner.arch }}-${{ matrix.build }}-${{ matrix.cc }}-${{ matrix.fortran }}
|
||||
ccache-${{ runner.os }}-${{ runner.arch }}-${{ matrix.build }}-${{ matrix.cc }}
|
||||
|
||||
- name: Configure ccache
|
||||
run: |
|
||||
@@ -89,7 +109,7 @@ jobs:
|
||||
echo "max_size = 300M" > ~/.ccache/ccache.conf
|
||||
echo "compression = true" >> ~/.ccache/ccache.conf
|
||||
ccache -s
|
||||
|
||||
|
||||
- name: Add gfortran runtime to link path
|
||||
if: matrix.build == 'make' && runner.os == 'macOS'
|
||||
run: |
|
||||
@@ -110,7 +130,7 @@ jobs:
|
||||
fi
|
||||
case "${{ matrix.build }}" in
|
||||
"make")
|
||||
make -j$(nproc) DYNAMIC_ARCH=1 USE_OPENMP=0 FC="ccache ${{ matrix.fortran }}"
|
||||
make -j$(nproc) DYNAMIC_ARCH=1 USE_OPENMP=0 CC="ccache ${{ matrix.cc }}" FC="ccache ${{ matrix.fortran }}"
|
||||
;;
|
||||
"cmake")
|
||||
mkdir build && cd build
|
||||
@@ -119,6 +139,7 @@ jobs:
|
||||
-DBUILD_WITHOUT_LAPACK=0 \
|
||||
-DCMAKE_VERBOSE_MAKEFILE=ON \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_C_COMPILER=${{ matrix.cc }} \
|
||||
-DCMAKE_Fortran_COMPILER=${{ matrix.fortran }} \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_Fortran_COMPILER_LAUNCHER=ccache \
|
||||
@@ -142,13 +163,13 @@ jobs:
|
||||
"make")
|
||||
MAKE_FLAGS='DYNAMIC_ARCH=1 USE_OPENMP=0'
|
||||
echo "::group::Tests in 'test' directory"
|
||||
make -C test $MAKE_FLAGS FC="ccache ${{ matrix.fortran }}"
|
||||
make -C test $MAKE_FLAGS CC="ccache ${{ matrix.cc }}" FC="ccache ${{ matrix.fortran }}"
|
||||
echo "::endgroup::"
|
||||
echo "::group::Tests in 'ctest' directory"
|
||||
make -C ctest $MAKE_FLAGS FC="ccache ${{ matrix.fortran }}"
|
||||
make -C ctest $MAKE_FLAGS CC="ccache ${{ matrix.cc }}" FC="ccache ${{ matrix.fortran }}"
|
||||
echo "::endgroup::"
|
||||
echo "::group::Tests in 'utest' directory"
|
||||
make -C utest $MAKE_FLAGS FC="ccache ${{ matrix.fortran }}"
|
||||
make -C utest $MAKE_FLAGS CC="ccache ${{ matrix.cc }}" FC="ccache ${{ matrix.fortran }}"
|
||||
echo "::endgroup::"
|
||||
;;
|
||||
"cmake")
|
||||
@@ -372,15 +393,15 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y gcc gfortran make
|
||||
|
||||
|
||||
- name: Build OpenBLAS
|
||||
run: |
|
||||
make -j${nproc}
|
||||
make -j${nproc}
|
||||
make -j${nproc} lapack-test
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
env:
|
||||
triple: riscv64-unknown-linux-gnu
|
||||
riscv_gnu_toolchain: https://github.com/riscv-collab/riscv-gnu-toolchain
|
||||
riscv_gnu_toolchain_version: 13.2.0
|
||||
riscv_gnu_toolchain_version: 15.1.0
|
||||
riscv_gnu_toolchain_nightly_download_path: /releases/download/2025.08.29/riscv64-glibc-ubuntu-22.04-llvm-nightly-2025.08.29-nightly.tar.xz
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -26,8 +26,8 @@ jobs:
|
||||
opts: TARGET=RISCV64_ZVL128B BINARY=64 ARCH=riscv64
|
||||
qemu_cpu: rv64,g=true,c=true,v=true,vext_spec=v1.0,vlen=128,elen=64
|
||||
- target: RISCV64_ZVL256B
|
||||
opts: TARGET=RISCV64_ZVL256B BINARY=64 ARCH=riscv64
|
||||
qemu_cpu: rv64,g=true,c=true,v=true,vext_spec=v1.0,vlen=256,elen=64
|
||||
opts: TARGET=RISCV64_ZVL256B BINARY=64 ARCH=riscv64 BUILD_BFLOAT16=1 BUILD_HFLOAT16=1
|
||||
qemu_cpu: rv64,g=true,c=true,v=true,vext_spec=v1.0,vlen=256,elen=64,zfh=true,zvfh=true,zvfbfwma=true
|
||||
- target: DYNAMIC_ARCH=1
|
||||
opts: TARGET=RISCV64_GENERIC BINARY=64 ARCH=riscv64 DYNAMIC_ARCH=1
|
||||
qemu_cpu: rv64,g=true,c=true,v=true,vext_spec=v1.0,vlen=256,elen=64
|
||||
@@ -40,10 +40,13 @@ jobs:
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install autoconf automake autotools-dev ninja-build make \
|
||||
libgomp1-riscv64-cross ccache
|
||||
libgomp1-riscv64-cross ccache qemu-kvm qemu-user libc6-riscv64-cross
|
||||
wget ${riscv_gnu_toolchain}/${riscv_gnu_toolchain_nightly_download_path}
|
||||
tar -xvf $(basename ${riscv_gnu_toolchain_nightly_download_path}) -C /opt
|
||||
|
||||
wget https://gist.github.com/martin-frbg/bb630e0de34978e578eeb496b1538d4e/raw/7fd8d971f327f7a517b8f5f7989479ff2b36f71f/qemu-riscv64-10.1-ubuntu24 -P /opt/riscv/bin -o riscv64-qemu
|
||||
mv /opt/riscv/bin/qemu-riscv64-10.1-ubuntu24 /opt/riscv/bin/qemu-riscv64
|
||||
chmod +x /opt/riscv/bin/qemu-riscv64
|
||||
|
||||
- name: Compilation cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
@@ -74,7 +77,7 @@ jobs:
|
||||
run: |
|
||||
export PATH="/opt/riscv/bin:$PATH"
|
||||
make TARGET=${{ matrix.target }} CFLAGS="-DTARGET=${{ matrix.target }}" \
|
||||
CC='${triple}-gcc' \
|
||||
CC='ccache clang --rtlib=compiler-rt -target ${triple} --sysroot /opt/riscv/sysroot --gcc-toolchain=/opt/riscv/lib/gcc/riscv64-unknown-linux-gnu/${riscv_gnu_toolchain_version}/' \
|
||||
AR='ccache ${triple}-ar' AS='ccache ${triple}-gcc' LD='ccache ${triple}-gcc' \
|
||||
RANLIB='ccache ${triple}-ranlib' \
|
||||
FC='ccache ${triple}-gfortran' ${{ matrix.opts }} \
|
||||
@@ -98,6 +101,8 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
export PATH="/opt/riscv/bin:$PATH"
|
||||
export LD_LIBRARY_PATH=/opt/riscv/sysroot/lib
|
||||
sudo ln -s /opt/riscv/sysroot/lib/ld-linux-riscv64-lp64d.so.1 /lib
|
||||
export QEMU_CPU=${{ matrix.qemu_cpu }}
|
||||
rm -rf ./test_out
|
||||
mkdir -p ./test_out
|
||||
@@ -134,6 +139,14 @@ jobs:
|
||||
wait
|
||||
while IFS= read -r -d $'\0' LOG; do cat $LOG ; FAILURES=1 ; done < <(grep -lZ FAIL ./test_out/*)
|
||||
if [[ ! -z $FAILURES ]]; then echo "==========" ; echo "== FAIL ==" ; echo "==========" ; echo ; exit 1 ; fi
|
||||
if [ "${{matrix.target}}" == "RISCV64_ZVL256B" ]; then
|
||||
qemu-riscv64 test/test_sbgemm &
|
||||
qemu-riscv64 test/test_sbgemv &
|
||||
qemu-riscv64 test/test_shgemm &
|
||||
qemu-riscv64 test/test_shgemv &
|
||||
qemu-riscv64 test/test_bgemm
|
||||
fi
|
||||
|
||||
|
||||
- name: netlib tests
|
||||
shell: bash
|
||||
|
||||
@@ -80,6 +80,7 @@ test/SBLAT3_3M.SUMM
|
||||
test/ZBLAT2.SUMM
|
||||
test/ZBLAT3.SUMM
|
||||
test/ZBLAT3_3M.SUMM
|
||||
test/SHBLAT2.SUMM
|
||||
test/SHBLAT3.SUMM
|
||||
test/SBBLAT2.SUMM
|
||||
test/SBBLAT3.SUMM
|
||||
@@ -98,6 +99,7 @@ test/sblat2
|
||||
test/sblat3
|
||||
test/sblat3_3m
|
||||
test/test_shgemm
|
||||
test/test_shgemv
|
||||
test/test_sbgemm
|
||||
test/test_sbgemv
|
||||
test/test_bgemm
|
||||
|
||||
+44
-6
@@ -9,7 +9,7 @@ project(OpenBLAS C ASM)
|
||||
|
||||
set(OpenBLAS_MAJOR_VERSION 0)
|
||||
set(OpenBLAS_MINOR_VERSION 3)
|
||||
set(OpenBLAS_PATCH_VERSION 30.dev)
|
||||
set(OpenBLAS_PATCH_VERSION 31)
|
||||
|
||||
set(OpenBLAS_VERSION "${OpenBLAS_MAJOR_VERSION}.${OpenBLAS_MINOR_VERSION}.${OpenBLAS_PATCH_VERSION}")
|
||||
|
||||
@@ -308,8 +308,8 @@ if (USE_OPENMP)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Fix "Argument list too long" for macOS with POWERPC or Intel CPUs
|
||||
if(APPLE AND (NOT CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64"))
|
||||
# Fix "Argument list too long" for macOS - mostly seen with older OS versions on POWERPC or Intel CPUs
|
||||
if(APPLE)
|
||||
# Use response files
|
||||
set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
# Always build static library first
|
||||
@@ -498,6 +498,11 @@ if (BUILD_SHARED_LIBS OR DELETE_STATIC_LIBS AND NOT ${SYMBOLPREFIX}${SYMBOLSUFFI
|
||||
else ()
|
||||
set (BBF16 0)
|
||||
endif()
|
||||
if (${BUILD_HFLOAT16})
|
||||
set (BHF16 1)
|
||||
else ()
|
||||
set (BHF16 0)
|
||||
endif()
|
||||
if (${BUILD_SINGLE})
|
||||
set (BS 1)
|
||||
else ()
|
||||
@@ -533,7 +538,7 @@ endif()
|
||||
#if (USE_PERL)
|
||||
message(STATUS "adding postbuild instruction to rename syms")
|
||||
add_custom_command(TARGET ${OpenBLAS_LIBNAME}_static POST_BUILD
|
||||
COMMAND perl ${PROJECT_SOURCE_DIR}/exports/gensymbol.pl "win2k" "${ARCH}" "${BU}" "${EXPRECISION_IN}" "${NO_CBLAS_IN}" "${NO_LAPACK_IN}" "${NO_LAPACKE_IN}" "${NEED2UNDERSCORES_IN}" "${ONLY_CBLAS_IN}" "${SYMBOLPREFIX}" "${SYMBOLSUFFIX}" "${BLD}" "${BBF16}" "${BS}" "${BD}" "${BC}" "${BZ}" > ${PROJECT_BINARY_DIR}/renamesyms.def
|
||||
COMMAND perl ${PROJECT_SOURCE_DIR}/exports/gensymbol.pl "win2k" "${ARCH}" "${BU}" "${EXPRECISION_IN}" "${NO_CBLAS_IN}" "${NO_LAPACK_IN}" "${NO_LAPACKE_IN}" "${NEED2UNDERSCORES_IN}" "${ONLY_CBLAS_IN}" "${SYMBOLPREFIX}" "${SYMBOLSUFFIX}" "${BLD}" "${BBF16}" "${BHF16}" "${BS}" "${BD}" "${BC}" "${BZ}" > ${PROJECT_BINARY_DIR}/renamesyms.def
|
||||
COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} -I${PROJECT_SOURCE_DIR} -I${PROJECT_BINARY_DIR} -c -o ${PROJECT_BINARY_DIR}/dllinit.o ${PROJECT_SOURCE_DIR}/exports/dllinit.c
|
||||
COMMAND lld-link -nodefaultlib:libcmt -defaultlib:${CRTLIB} ${CMAKE_LINKER_FLAGS} -errorlimit:0 -def:${PROJECT_BINARY_DIR}/renamesyms.def ${PROJECT_BINARY_DIR}/dllinit.o $<TARGET_FILE:${OpenBLAS_LIBNAME}_static> -wholearchive:$<TARGET_FILE:${OpenBLAS_LIBNAME}_static> -dll -out:$<TARGET_FILE_DIR:${OpenBLAS_LIBNAME}_static>/${OpenBLAS_LIBNAME}.dll -implib:$<TARGET_FILE_DIR:${OpenBLAS_LIBNAME}_static>/${OpenBLAS_LIBNAME}.dll.a ${PDBOPT}
|
||||
#COMMAND lld-link -nodefaultlib:libcmt -defaultlib:msvcrt ${CMAKE_LINKER_FLAGS} -errorlimit:0 -def:${PROJECT_BINARY_DIR}/renamesyms.def ${PROJECT_BINARY_DIR}/dllinit.o $<TARGET_FILE:${OpenBLAS_LIBNAME}_static> -wholearchive:$<TARGET_FILE:${OpenBLAS_LIBNAME}_static> -dll -out:$<TARGET_FILE_DIR:${OpenBLAS_LIBNAME}_static>/${OpenBLAS_LIBNAME}.dll -implib:$<TARGET_FILE_DIR:${OpenBLAS_LIBNAME}_static>/${OpenBLAS_LIBNAME}.dll.a
|
||||
@@ -543,13 +548,13 @@ message(STATUS "adding postbuild instruction to rename syms")
|
||||
else ()
|
||||
if (NOT USE_PERL)
|
||||
add_custom_command(TARGET ${OpenBLAS_LIBNAME}_shared POST_BUILD
|
||||
COMMAND sh ${PROJECT_SOURCE_DIR}/exports/gensymbol "objcopy" "${ARCH}" "${BU}" "${EXPRECISION_IN}" "${NO_CBLAS_IN}" "${NO_LAPACK_IN}" "${NO_LAPACKE_IN}" "${NEED2UNDERSCORES_IN}" "${ONLY_CBLAS_IN}" \"${SYMBOLPREFIX}\" \"${SYMBOLSUFFIX}\" "${BLD}" "${BBF16}" "${BS}" "${BD}" "${BC}" "${BZ}" > ${PROJECT_BINARY_DIR}/objcopy.def
|
||||
COMMAND sh ${PROJECT_SOURCE_DIR}/exports/gensymbol "objcopy" "${ARCH}" "${BU}" "${EXPRECISION_IN}" "${NO_CBLAS_IN}" "${NO_LAPACK_IN}" "${NO_LAPACKE_IN}" "${NEED2UNDERSCORES_IN}" "${ONLY_CBLAS_IN}" \"${SYMBOLPREFIX}\" \"${SYMBOLSUFFIX}\" "${BLD}" "${BBF16}" "${BHF16}" "${BS}" "${BD}" "${BC}" "${BZ}" > ${PROJECT_BINARY_DIR}/objcopy.def
|
||||
COMMAND objcopy --redefine-syms ${PROJECT_BINARY_DIR}/objcopy.def ${PROJECT_BINARY_DIR}/lib/${OpenBLAS_LIBNAME}.so
|
||||
COMMENT "renaming symbols"
|
||||
)
|
||||
else()
|
||||
add_custom_command(TARGET ${OpenBLAS_LIBNAME}_shared POST_BUILD
|
||||
COMMAND perl ${PROJECT_SOURCE_DIR}/exports/gensymbol.pl "objcopy" "${ARCH}" "${BU}" "${EXPRECISION_IN}" "${NO_CBLAS_IN}" "${NO_LAPACK_IN}" "${NO_LAPACKE_IN}" "${NEED2UNDERSCORES_IN}" "${ONLY_CBLAS_IN}" \"${SYMBOLPREFIX}\" \"${SYMBOLSUFFIX}\" "${BLD}" "${BBF16}" "${BS}" "${BD}" "${BC}" "${BZ}" > ${PROJECT_BINARY_DIR}/objcopy.def
|
||||
COMMAND perl ${PROJECT_SOURCE_DIR}/exports/gensymbol.pl "objcopy" "${ARCH}" "${BU}" "${EXPRECISION_IN}" "${NO_CBLAS_IN}" "${NO_LAPACK_IN}" "${NO_LAPACKE_IN}" "${NEED2UNDERSCORES_IN}" "${ONLY_CBLAS_IN}" \"${SYMBOLPREFIX}\" \"${SYMBOLSUFFIX}\" "${BLD}" "${BBF16}" "${BHF16}" "${BS}" "${BD}" "${BC}" "${BZ}" > ${PROJECT_BINARY_DIR}/objcopy.def
|
||||
COMMAND objcopy --redefine-syms ${PROJECT_BINARY_DIR}/objcopy.def ${PROJECT_BINARY_DIR}/lib/lib${OpenBLAS_LIBNAME}.so
|
||||
COMMENT "renaming symbols"
|
||||
)
|
||||
@@ -703,6 +708,39 @@ if(NOT NO_LAPACKE)
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/lapack-netlib/LAPACKE/include/lapacke_mangling_with_flags.h.in "${CMAKE_BINARY_DIR}/lapacke_mangling.h"
|
||||
)
|
||||
install (FILES ${CMAKE_BINARY_DIR}/lapacke_mangling.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
if (NOT (x${SYMBOLPREFIX}${SYMBOLSUFFIX} STREQUAL "x"))
|
||||
message (STATUS "Generating lapacke.h in ${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
set(LAPACKE_H ${CMAKE_BINARY_DIR}/generated/lapacke.h)
|
||||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/lapack-netlib/LAPACKE/include/lapacke.h LAPACKE_H_CONTENTS)
|
||||
if (NOT ${SYMBOLPREFIX} STREQUAL "")
|
||||
string(REGEX REPLACE "(LAPACKE_*)" " ${SYMBOLPREFIX}\\1" LAPACKE_H_CONTENTS_NEW "${LAPACKE_H_CONTENTS}")
|
||||
string(REPLACE "_ ${SYMBOLPREFIX}LAPACKE_H_" "_LAPACKE_H_" LAPACKE_H_CONTENTS ${LAPACKE_H_CONTENTS_NEW})
|
||||
string(REPLACE "${SYMBOLPREFIX}LAPACKE_malloc" "LAPACKE_malloc" LAPACKE_H_CONTENTS_NEW ${LAPACKE_H_CONTENTS})
|
||||
string(REPLACE "${SYMBOLPREFIX}LAPACKE_free" "LAPACKE_free" LAPACKE_H_CONTENTS ${LAPACKE_H_CONTENTS_NEW})
|
||||
set(LAPACKE_H_CONTENTS_NEW ${LAPACKE_H_CONTENTS})
|
||||
endif()
|
||||
if (NOT ${SYMBOLSUFFIX} STREQUAL "")
|
||||
string(REGEX REPLACE "(${SYMBOLPREFIX}LAPACKE_[a-z1-9]*[^ (]*)" "\\1${SYMBOLSUFFIX}" LAPACKE_H_CONTENTS_NEW "${LAPACKE_H_CONTENTS}")
|
||||
string(REPLACE "#define${SYMBOLSUFFIX}" "#define" LAPACKE_H_CONTENTS ${LAPACKE_H_CONTENTS_NEW})
|
||||
string(REPLACE "LAPACKE_malloc${SYMBOLSUFFIX}" "LAPACKE_malloc" LAPACKE_H_CONTENTS_NEW ${LAPACKE_H_CONTENTS})
|
||||
string(REPLACE "LAPACKE_free${SYMBOLSUFFIX}" "LAPACKE_free" LAPACKE_H_CONTENTS ${LAPACKE_H_CONTENTS_NEW})
|
||||
set(LAPACKE_H_CONTENTS_NEW ${LAPACKE_H_CONTENTS})
|
||||
endif()
|
||||
file(WRITE ${LAPACKE_H} "${LAPACKE_H_CONTENTS_NEW}")
|
||||
install (FILES ${LAPACKE_H} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
message (STATUS "Generating lapack.h in ${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
set(LAPACK_H ${CMAKE_BINARY_DIR}/generated/lapack.h)
|
||||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/lapack-netlib/LAPACKE/include/lapack.h LAPACK_H_CONTENTS)
|
||||
if (NOT ${SYMBOLPREFIX} STREQUAL "")
|
||||
string(REGEX REPLACE "(LAPACK_[a-z1-9]*[ \(][.\)]*)" "${SYMBOLPREFIX}\\1" LAPACK_H_CONTENTS_NEW "${LAPACK_H_CONTENTS}")
|
||||
set(LAPACK_H_CONTENTS ${LAPACK_H_CONTENTS_NEW})
|
||||
endif()
|
||||
if (NOT ${SYMBOLSUFFIX} STREQUAL "")
|
||||
string(REGEX REPLACE "(${SYMBOLPREFIX}LAPACK_[a-z1-9]*)([ \(].\)" "\\1${SYMBOLSUFFIX}\\2" LAPACK_H_CONTENTS_NEW "${LAPACK_H_CONTENTS}")
|
||||
endif()
|
||||
file(WRITE ${LAPACK_H} "${LAPACK_H_CONTENTS_NEW}")
|
||||
install (FILES ${LAPACK_H} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Install pkg-config files
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
* Annop Wongwathanarat <annop.wongwathanarat@arm.com>
|
||||
* Optimizations and other improvements targeting AArch64
|
||||
|
||||
* Anna Mayne <anna.mayne@arm.com>
|
||||
* Optimizations and other improvements targeting AArch64
|
||||
|
||||
## Previous Developers
|
||||
|
||||
* Zaheer Chothia <zaheer.chothia@gmail.com>
|
||||
@@ -267,3 +270,5 @@ In chronological order:
|
||||
* [2025-05-29] Optimise axpby kernel for RISCV64_ZVL256B
|
||||
* [2025-06-05] Optimise hbmv kernel for RISCV64_ZVL256B
|
||||
|
||||
* Anna Mayne <anna.mayne@arm.com>
|
||||
* [2025-11-19] Update thread throttling profile for SGEMV on NEOVERSEV1 and NEOVERSEV2
|
||||
|
||||
+116
@@ -1,4 +1,120 @@
|
||||
OpenBLAS ChangeLog
|
||||
====================================================================
|
||||
Version 0.3.31
|
||||
15-Jan-2025
|
||||
|
||||
general:
|
||||
- reverted a matrix partitioning optimization from 0.3.30 that could lead to
|
||||
race conditions and subsequent invalid results in GEMM
|
||||
- added the bfloat16 extensions BGEMM and BGEMV
|
||||
- added a BLAS interface for the ?GEMM_BATCH extensions
|
||||
- added the BLAS extensions ?GEMM_BATCH_STRIDED and their CBLAS interface
|
||||
- added the basic infrastructure for half-precision float (FP16) format
|
||||
using SH prefix
|
||||
- reimplemented the LAPACK SLAED3/DLAED3 function using multithreading, thereby
|
||||
improving the performance of the SSYEVD/DSYEVD eigensolver for symmetric matrices
|
||||
on all platforms
|
||||
- limited the number of retries for initial memory allocation to avoid infinite
|
||||
hanging on low-memory systems
|
||||
- fixed a thread lockup situation encountered with python 3.9 or older and numpy
|
||||
- introduced a problem size threshold for multithreading in STRMV/DTRMV
|
||||
- introduced a problem size threshold for multithreading in CHER/CHER2/CHPR/CHPR2
|
||||
and ZHER/ZHER2/ZHPR/ZHPR2
|
||||
- improved the problem size thresholds for multithreading in SGER/DGER
|
||||
- improved autodetection of the Fortran compiler
|
||||
- fixed passing of the INTERFACE64=1 option to the flang-new compiler
|
||||
- fixed a potential deadlock in multithreaded code after calling fork()
|
||||
- fixed builds using CMake on FreeBSD
|
||||
- fixed builds using CMake from within Cygwin on Windows
|
||||
- fixed builds using CMake and the NVHPC compiler on ARM64
|
||||
- fixed CMake build error from misdetecting compiler or OpenMP versions
|
||||
- improved contents of the CMake-generated OpenBLASConfig.cmake file
|
||||
- added support for cross-compilation to RISCV targets via CMake
|
||||
- fixed cross-compilation to x86 targets from non-x86 architectures
|
||||
- fixed failure to install cblas.h if NO_CBLAS=0 was specified
|
||||
- fixed missing user-defined pre- and postfixes on functions in lapack.h,lapacke.h
|
||||
- included fixes from the Reference-LAPACK project:
|
||||
- fix ordering bug in ?LAED/?LASD (Reference-LAPACK PR 1140)
|
||||
- revert changes in ?GEEV from PR 1129 (Reference-LAPACK PR 1142)
|
||||
- fix workspace allocation in LAPACKE_?TRSEN (Reference-LAPACK PR 1144)
|
||||
|
||||
riscv:
|
||||
- added optimized SBGEMM kernels for ZVL128B and ZVL256B targets
|
||||
- added optimized SHGEMM kernels for ZVL128B and ZVL256B targets
|
||||
- added optimized SBGEMV and SHGEMV kernels for ZVL128B/ZVL256B
|
||||
- improved performance of the GEMV kernel for ZVL256B
|
||||
- improved the performance of the CROT and ZROT kernels for ZVL128B and x280
|
||||
- improved the detection of RVV1.0 capability
|
||||
- improved performance of the matrix packing helper functions for ZVL128B and ZVL256B
|
||||
- improved performance of OMATCOPY for ZVL128B and ZVL256B
|
||||
|
||||
arm:
|
||||
- fixed spurious executable stack in the getarch utility
|
||||
|
||||
arm64:
|
||||
- fixed spurious executable stack in the getarch utility
|
||||
- fixed compiler warnings arising from the timer macro RPCC
|
||||
- fixed cache size detection for Qualcomm Oryon under Windows on Arm
|
||||
- fixed argument handling in the default SVE kernel for SDOT/DDOT
|
||||
- building the BFLOAT16 kernels is now enabled by default
|
||||
- improved the overall performance of GEMM,SYMM and HEMM on A64FX
|
||||
- improved the performance of SDOT/DDOT on A64FX
|
||||
- improved the multithreading performance of SDOT/DDOT on A64FX by
|
||||
introduction of a throttling table matching thread count to problem size
|
||||
- improved the performance of SGER/DGER on A64FX and NEOVERSEV1
|
||||
- improved the multithreading performance of GEMM on A64FX and NEOVERSEV1
|
||||
- improved the performance of the GEMV kernel for SVE-capable targets
|
||||
- improved the multithreading performance of SGEMM on NEOVERSEV1 and V2
|
||||
- added optimized SAXPY/DAXPY SVE kernels for A64FX and NEOVERSEV1
|
||||
- added optimized BGEMM and BGEMV kernels for NEOVERSEV1
|
||||
- added an optimized BGEMM kernel for NEOVERSEN2
|
||||
- added support for the NEOVERSEV2 cpu
|
||||
- added dedicated support for the Apple M4 cpu as VORTEXM4
|
||||
- added optimized SGEMM/SSYMM/STRMM/SSYRK/SSYR2K for SME-capable targets
|
||||
(ARMV9SME and VORTEXM4)
|
||||
- improved the precision of the SNRM2 kernel
|
||||
- added cpu autodetection and compiler settings for Ampere One processors
|
||||
- fixed cpu autodetection for Apple M systems running Linux
|
||||
- fixed building on MacOS with AppleClang,gfortran and xcode v16 or newer
|
||||
- fixed several errors in the C code replacements for the complex and double
|
||||
precision complex LAPACK functions that get used (only) when compiling with
|
||||
Microsoft C and NOFORTRAN=1 under MS Windows
|
||||
|
||||
power:
|
||||
- added initial support for the POWER11 architecture
|
||||
- improved performance of DGEMM and DGEMV on POWER10
|
||||
- fixed the default compiler flags to use "-O3" instead of the possibly unsafe
|
||||
"-Ofast"
|
||||
- fixed building under MacOS (for old G4 Macs) with CMake
|
||||
- fixed potential miscompilation of DGEMV and other assembly kernels by gcc15.1
|
||||
- fixed compilation with recent versions of flang
|
||||
|
||||
loongarch64:
|
||||
- fixed warnings and potential inaccuracies arising from incorrect saving of registers
|
||||
- fixed enumeration of logical cores on big NUMA servers
|
||||
- fixed building with LLVM and the INTERFACE64=1 option
|
||||
|
||||
x86:
|
||||
- fixed building the GEMM3M kernels for the GENERIC target
|
||||
- fixed several errors in the C code replacements for the complex and double
|
||||
precision complex LAPACK functions that get used (only) when compiling with
|
||||
Microsoft C and NOFORTRAN=1 under MS Windows
|
||||
|
||||
x86_64:
|
||||
- added cpu autodetection for Intel Lunar Lake (Core Ultra 200V)
|
||||
- changed all ?MIN and ?MAX assembly kernels to use unaligned operations
|
||||
- fixed several errors in the C code replacements for the complex and double
|
||||
precision complex LAPACK functions that get used (only) when compiling with
|
||||
Microsoft C and NOFORTRAN=1 under MS Windows
|
||||
- fixed potential crashes in builds for Cooper Lake, Sapphire Rapids or Zen5 cpus
|
||||
under MS Windows
|
||||
|
||||
zarch:
|
||||
- added support for building with CMake
|
||||
|
||||
sparc:
|
||||
- fixed a potential crash in the DNRM2 kernel
|
||||
|
||||
====================================================================
|
||||
Version 0.3.30
|
||||
19-Jun-2025
|
||||
|
||||
+21
-6
@@ -1,16 +1,31 @@
|
||||
pipeline {
|
||||
agent {
|
||||
docker {
|
||||
image 'osuosl/ubuntu-ppc64le:18.04'
|
||||
}
|
||||
}
|
||||
agent none
|
||||
stages {
|
||||
stage('Build') {
|
||||
stage('GCC build') {
|
||||
agent {
|
||||
docker {
|
||||
image 'osuosl/ubuntu-ppc64le:18.04' // gcc 7, gfortran 7
|
||||
}
|
||||
}
|
||||
steps {
|
||||
checkout scm
|
||||
sh 'sudo apt update'
|
||||
sh 'sudo apt install gfortran -y'
|
||||
sh 'make clean && make'
|
||||
}
|
||||
}
|
||||
stage('Clang build') {
|
||||
agent {
|
||||
docker {
|
||||
image 'osuosl/ubuntu-ppc64le:20.04' // clang 10, gfortran 9
|
||||
}
|
||||
}
|
||||
steps {
|
||||
checkout scm
|
||||
sh 'sudo apt update'
|
||||
sh 'sudo apt install -y clang gfortran'
|
||||
sh 'make clean && make CC=clang'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,11 @@ endif
|
||||
ifeq ($(CORE), ARMV9SME)
|
||||
CCOMMON_OPT += -march=armv9-a+sve2+sme
|
||||
FCOMMON_OPT += -march=armv9-a+sve2
|
||||
ifdef OS_WINDOWS
|
||||
ifeq ($(C_COMPILER), CLANG)
|
||||
CCOMMON_OPT += --aarch64-stack-hazard-size=0
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CORE), CORTEXA53)
|
||||
@@ -303,6 +308,20 @@ FCOMMON_OPT += -march=armv8.3-a
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CORE), VORTEXM4)
|
||||
ifneq ($(C_COMPILER), GCC)
|
||||
ifeq ($(APPLECLANG),1)
|
||||
CCOMMON_OPT += -march=armv8.4-a+sme
|
||||
else
|
||||
CCOMMON_OPT += -march=armv8.4-a+sme
|
||||
override LDFLAGS += -lclang_rt_builtins-aarch64
|
||||
endif
|
||||
else
|
||||
CCOMMON_OPT += -march=armv8.4-a
|
||||
endif
|
||||
FCOMMON_OPT += -march=armv8.4-a
|
||||
endif
|
||||
|
||||
ifeq (1, $(filter 1,$(GCCVERSIONGTEQ9) $(ISCLANG)))
|
||||
ifeq ($(CORE), TSV110)
|
||||
CCOMMON_OPT += -march=armv8.2-a -mtune=tsv110
|
||||
|
||||
+20
-2
@@ -93,9 +93,27 @@ endif
|
||||
|
||||
ifneq ($(OSNAME), AIX)
|
||||
ifneq ($(NO_LAPACKE), 1)
|
||||
@cp $(NETLIB_LAPACK_DIR)/LAPACKE/include/lapacke.h lapacke_h.tmp
|
||||
ifdef SYMBOLPREFIX
|
||||
@sed 's/LAPACKE_[a-z1-9].[^() ]*/$(SYMBOLPREFIX)&/g' lapacke_h.tmp > lapacke.tmp2
|
||||
@mv lapacke.tmp2 lapacke_h.tmp
|
||||
endif
|
||||
ifdef SYMBOLSUFFIX
|
||||
@sed 's/LAPACKE_[a-z1-9].[^() ]*/&$(SYMBOLSUFFIX)/g' lapacke_h.tmp > lapacke.tmp2
|
||||
@mv lapacke.tmp2 lapacke_h.tmp
|
||||
endif
|
||||
@-install -m644 lapacke_h.tmp "$(DESTDIR)$(OPENBLAS_INCLUDE_DIR)/lapacke.h"
|
||||
@echo Copying LAPACKE header files to $(DESTDIR)$(OPENBLAS_INCLUDE_DIR)
|
||||
@-install -m644 $(NETLIB_LAPACK_DIR)/LAPACKE/include/lapack.h "$(DESTDIR)$(OPENBLAS_INCLUDE_DIR)/lapack.h"
|
||||
@-install -m644 $(NETLIB_LAPACK_DIR)/LAPACKE/include/lapacke.h "$(DESTDIR)$(OPENBLAS_INCLUDE_DIR)/lapacke.h"
|
||||
@cp $(NETLIB_LAPACK_DIR)/LAPACKE/include/lapack.h lapack_h.tmp
|
||||
ifdef SYMBOLPREFIX
|
||||
@sed 's/LAPACK_[a-z1-9]*(\.\.\.)/$(SYMBOLPREFIX)&/g' lapack_h.tmp > lapack.tmp2
|
||||
@mv lapack.tmp2 lapack_h.tmp
|
||||
endif
|
||||
ifdef SYMBOLSUFFIX
|
||||
@sed 's/\(#define $(SYMBOLPREFIX)LAPACK_[a-z1-9].*\)\((...)\)/\1$(SYMBOLSUFFIX)\2/g' lapack_h.tmp > lapack.tmp2
|
||||
@mv lapack.tmp2 lapack_h.tmp
|
||||
endif
|
||||
@-install -m644 lapack_h.tmp "$(DESTDIR)$(OPENBLAS_INCLUDE_DIR)/lapack.h"
|
||||
@-install -m644 $(NETLIB_LAPACK_DIR)/LAPACKE/include/lapacke_config.h "$(DESTDIR)$(OPENBLAS_INCLUDE_DIR)/lapacke_config.h"
|
||||
@-install -m644 $(NETLIB_LAPACK_DIR)/LAPACKE/include/lapacke_mangling_with_flags.h.in "$(DESTDIR)$(OPENBLAS_INCLUDE_DIR)/lapacke_mangling.h"
|
||||
@-install -m644 $(NETLIB_LAPACK_DIR)/LAPACKE/include/lapacke_utils.h "$(DESTDIR)$(OPENBLAS_INCLUDE_DIR)/lapacke_utils.h"
|
||||
|
||||
@@ -118,6 +118,10 @@ ifeq ($(F_COMPILER), GFORTRAN)
|
||||
FCOMMON_OPT += -fno-optimize-sibling-calls
|
||||
endif
|
||||
|
||||
ifeq ($(F_COMPILER), FLANGNEW)
|
||||
override FCOMMON_OPT := $(filter-out -frecursive,$(FCOMMON_OPT))
|
||||
endif
|
||||
|
||||
FLAMEPATH = $(HOME)/flame/lib
|
||||
|
||||
#ifeq ($(CORE), CELL)
|
||||
@@ -147,12 +151,15 @@ endif
|
||||
ifdef BINARY64
|
||||
|
||||
|
||||
#Skip C/Fortran compiler combination checks in AIX if NO_FORTRAN or ONLY_CBLAS is set
|
||||
ifeq ($(filter 1,$(NO_FORTRAN) $(ONLY_CBLAS)),)
|
||||
ifeq ($(C_COMPILER)$(F_COMPILER)$(OSNAME), GCCIBMAIX)
|
||||
$(error Using GCC and XLF on AIX is not a supported combination.)
|
||||
endif
|
||||
ifeq ($(C_COMPILER)$(F_COMPILER)$(OSNAME), CLANGGFORTRANAIX)
|
||||
$(error Using Clang and gFortran on AIX is not a supported combination.)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OSNAME), AIX)
|
||||
ifeq ($(C_COMPILER), GCC)
|
||||
|
||||
+10
-13
@@ -6,23 +6,20 @@ ifeq ($(CORE), x280)
|
||||
CCOMMON_OPT += -march=rv64imafdcv_zba_zbb_zfh_zvl512b -mabi=lp64d
|
||||
FCOMMON_OPT += -march=rv64imafdcv_zba_zbb_zfh -mabi=lp64d -static
|
||||
endif
|
||||
ifeq ($(CORE), RISCV64_ZVL256B)
|
||||
RISCV64_OPT = rv64imafdcv
|
||||
ifeq ($(BUILD_HFLOAT16), 1)
|
||||
CCOMMON_OPT += -march=rv64imafdcv_zvl256b_zvfh_zfh -mabi=lp64d
|
||||
FCOMMON_OPT += -march=rv64imafdcv_zvfh_zfh -mabi=lp64d
|
||||
else
|
||||
CCOMMON_OPT += -march=rv64imafdcv_zvl256b -mabi=lp64d
|
||||
FCOMMON_OPT += -march=rv64imafdcv -mabi=lp64d
|
||||
RISCV64_OPT := $(RISCV64_OPT)_zvfh_zfh
|
||||
endif
|
||||
ifeq ($(BUILD_BFLOAT16), 1)
|
||||
RISCV64_OPT := $(RISCV64_OPT)_zvfbfwma
|
||||
endif
|
||||
ifeq ($(CORE), RISCV64_ZVL256B)
|
||||
CCOMMON_OPT += -march=$(RISCV64_OPT)_zvl256b -mabi=lp64d
|
||||
FCOMMON_OPT += -march=$(RISCV64_OPT) -mabi=lp64d
|
||||
endif
|
||||
ifeq ($(CORE), RISCV64_ZVL128B)
|
||||
ifeq ($(BUILD_HFLOAT16), 1)
|
||||
CCOMMON_OPT += -march=rv64imafdcv_zvfh_zfh -mabi=lp64d
|
||||
FCOMMON_OPT += -march=rv64imafdcv_zvfh_zfh -mabi=lp64d
|
||||
else
|
||||
CCOMMON_OPT += -march=rv64imafdcv -mabi=lp64d
|
||||
FCOMMON_OPT += -march=rv64imafdcv -mabi=lp64d
|
||||
endif
|
||||
CCOMMON_OPT += -march=$(RISCV64_OPT) -mabi=lp64d
|
||||
FCOMMON_OPT += -march=$(RISCV64_OPT) -mabi=lp64d
|
||||
endif
|
||||
ifeq ($(CORE), RISCV64_GENERIC)
|
||||
CCOMMON_OPT += -march=rv64imafdc -mabi=lp64d
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
# This library's version
|
||||
VERSION = 0.3.30.dev
|
||||
VERSION = 0.3.31
|
||||
|
||||
# If you set this prefix, the library name will be lib$(LIBNAMESUFFIX)openblas.a
|
||||
# and lib$(LIBNAMESUFFIX)openblas.so, with a matching soname in the shared library
|
||||
|
||||
+12
-5
@@ -331,6 +331,7 @@ HAVE_SSE5=
|
||||
HAVE_AVX=
|
||||
HAVE_AVX2=
|
||||
HAVE_FMA3=
|
||||
HAVE_SME=
|
||||
include $(TOPDIR)/Makefile_kernel.conf
|
||||
endif
|
||||
|
||||
@@ -427,7 +428,7 @@ ifndef MACOSX_DEPLOYMENT_TARGET
|
||||
ifeq ($(ARCH), arm64)
|
||||
export MACOSX_DEPLOYMENT_TARGET=11.0
|
||||
export NO_SVE = 1
|
||||
export NO_SME = 1
|
||||
# export NO_SME = 1
|
||||
else
|
||||
export MACOSX_DEPLOYMENT_TARGET=10.8
|
||||
endif
|
||||
@@ -441,7 +442,7 @@ ifeq (x$(XCVER), x 15)
|
||||
CCOMMON_OPT += -Wl,-ld_classic
|
||||
FCOMMON_OPT += -Wl,-ld_classic
|
||||
endif
|
||||
ifeq (x$(XCVER), x 16)
|
||||
ifeq ($(shell [ $(XCVER) -ge 16 ] && echo yes),yes)
|
||||
override CEXTRALIB := $(filter-out(-lto_library, $(CEXTRALIB)))
|
||||
endif
|
||||
endif
|
||||
@@ -721,6 +722,11 @@ DYNAMIC_CORE += A64FX
|
||||
endif
|
||||
ifneq ($(NO_SME), 1)
|
||||
DYNAMIC_CORE += ARMV9SME
|
||||
ifeq ($(OSNAME), Darwin)
|
||||
ifneq ($(C_COMPILER), GCC)
|
||||
DYNAMIC_CORE += VORTEXM4
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
DYNAMIC_CORE += THUNDERX
|
||||
DYNAMIC_CORE += THUNDERX2T99
|
||||
@@ -887,7 +893,7 @@ NO_BINARY_MODE = 1
|
||||
BINARY_DEFINED = 1
|
||||
ifdef INTERFACE64
|
||||
ifneq ($(INTERFACE64), 0)
|
||||
ifeq ($(F_COMPILER), GFORTRAN)
|
||||
ifeq ($(F_COMPILER), $(filter $(F_COMPILER),GFORTRAN FLANGNEW))
|
||||
FCOMMON_OPT += -fdefault-integer-8
|
||||
endif
|
||||
ifeq ($(F_COMPILER), FLANG)
|
||||
@@ -902,7 +908,7 @@ NO_BINARY_MODE = 1
|
||||
BINARY_DEFINED = 1
|
||||
ifdef INTERFACE64
|
||||
ifneq ($(INTERFACE64), 0)
|
||||
ifeq ($(F_COMPILER), GFORTRAN)
|
||||
ifeq ($(F_COMPILER), $(filter $(F_COMPILER),GFORTRAN FLANGNEW))
|
||||
FCOMMON_OPT += -fdefault-integer-8
|
||||
endif
|
||||
ifeq ($(F_COMPILER), FLANG)
|
||||
@@ -917,7 +923,7 @@ NO_BINARY_MODE = 1
|
||||
BINARY_DEFINED = 1
|
||||
ifdef INTERFACE64
|
||||
ifneq ($(INTERFACE64), 0)
|
||||
ifeq ($(F_COMPILER), GFORTRAN)
|
||||
ifeq ($(F_COMPILER), $(filter $(F_COMPILER),GFORTRAN FLANGNEW))
|
||||
FCOMMON_OPT += -fdefault-integer-8
|
||||
endif
|
||||
ifeq ($(F_COMPILER), FLANG)
|
||||
@@ -1896,6 +1902,7 @@ ifndef NO_MSA
|
||||
export HAVE_MSA
|
||||
export MSA_FLAGS
|
||||
endif
|
||||
export HAVE_SME
|
||||
export KERNELDIR
|
||||
export FUNCTION_PROFILE
|
||||
export TARGET_CORE
|
||||
|
||||
@@ -111,6 +111,7 @@ THUNDERX2T99
|
||||
TSV110
|
||||
THUNDERX3T110
|
||||
VORTEX
|
||||
VORTEXM4
|
||||
A64FX
|
||||
ARMV8SVE
|
||||
ARMV9SME
|
||||
|
||||
+22
-20
@@ -95,7 +95,7 @@ jobs:
|
||||
vmImage: 'windows-latest'
|
||||
steps:
|
||||
- script: |
|
||||
mingw32-make CC=gcc FC=gfortran DYNAMIC_ARCH=1 DYNAMIC_LIST="SANDYBRIDGE"
|
||||
mingw32-make CC=gcc NOLAPACK=1 DYNAMIC_ARCH=1 DYNAMIC_LIST="SANDYBRIDGE"
|
||||
|
||||
- job: Windows_clang_cmake
|
||||
pool:
|
||||
@@ -155,7 +155,7 @@ jobs:
|
||||
|
||||
- job: OSX_OpenMP
|
||||
pool:
|
||||
vmImage: 'macOS-13'
|
||||
vmImage: 'macOS-14'
|
||||
steps:
|
||||
- script: |
|
||||
brew update
|
||||
@@ -165,19 +165,19 @@ jobs:
|
||||
|
||||
- job: OSX_GCC_Nothreads
|
||||
pool:
|
||||
vmImage: 'macOS-13'
|
||||
vmImage: 'macOS-14'
|
||||
steps:
|
||||
- script: |
|
||||
brew update
|
||||
make USE_THREADS=0 CC=gcc-13 FC=gfortran-13
|
||||
|
||||
- job: OSX_GCC12
|
||||
- job: OSX_GCC15
|
||||
pool:
|
||||
vmImage: 'macOS-latest'
|
||||
steps:
|
||||
- script: |
|
||||
brew update
|
||||
make CC=gcc-12 FC=gfortran-12
|
||||
make CC=gcc-15 FC=gfortran-15
|
||||
|
||||
- job: OSX_LLVM_flangnew
|
||||
pool:
|
||||
@@ -201,7 +201,7 @@ jobs:
|
||||
- script: |
|
||||
brew update
|
||||
brew install llvm libomp
|
||||
make TARGET=CORE2 USE_OPENMP=1 DYNAMIC_ARCH=1 CC=/usr/local/opt/llvm/bin/clang NOFORTRAN=1
|
||||
make TARGET=CORE2 USE_OPENMP=1 DYNAMIC_ARCH=1 DYNAMIC_LIST='NEHALEM HASWELL SKYLAKEX' CC=/usr/local/opt/llvm/bin/clang NOFORTRAN=1
|
||||
|
||||
- job: OSX_OpenMP_Clang_cmake
|
||||
pool:
|
||||
@@ -215,13 +215,13 @@ jobs:
|
||||
brew install llvm libomp
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DTARGET=CORE2 -DUSE_OPENMP=1 -DINTERFACE64=1 -DDYNAMIC_ARCH=1 -DCMAKE_C_COMPILER=/usr/local/opt/llvm/bin/clang -DNOFORTRAN=1 -DNO_AVX512=1 ..
|
||||
cmake -DTARGET=CORE2 -DUSE_OPENMP=1 -DINTERFACE64=1 -DDYNAMIC_ARCH=1 -DDYNAMIC_LIST='NEHALEM HASWELL SKYLAKEX' -DCMAKE_C_COMPILER=/usr/local/opt/llvm/bin/clang -DNOFORTRAN=1 -DNO_AVX512=1 ..
|
||||
make
|
||||
ctest
|
||||
|
||||
- job: OSX_dynarch_cmake
|
||||
pool:
|
||||
vmImage: 'macOS-13'
|
||||
vmImage: 'macOS-14'
|
||||
variables:
|
||||
LD_LIBRARY_PATH: /usr/local/opt/llvm/lib
|
||||
LIBRARY_PATH: /usr/local/opt/llvm/lib
|
||||
@@ -268,7 +268,7 @@ jobs:
|
||||
|
||||
- job: OSX_NDK_ARMV7
|
||||
pool:
|
||||
vmImage: 'macOS-13'
|
||||
vmImage: 'macOS-14'
|
||||
steps:
|
||||
- script: |
|
||||
brew update
|
||||
@@ -278,35 +278,37 @@ jobs:
|
||||
|
||||
- job: OSX_IOS_ARMV8
|
||||
pool:
|
||||
vmImage: 'macOS-13'
|
||||
vmImage: 'macOS-14'
|
||||
variables:
|
||||
CC: /Applications/Xcode_14.2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
|
||||
CFLAGS: -O2 -Wno-macro-redefined -isysroot /Applications/Xcode_14.2.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk -arch arm64 -miphoneos-version-min=10.0
|
||||
CC: /Applications/Xcode_16.2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
|
||||
CFLAGS: -O2 -Wno-macro-redefined -isysroot /Applications/Xcode_16.2.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.2.sdk -arch arm64 -miphoneos-version-min=10.0
|
||||
steps:
|
||||
- script: |
|
||||
ls /Applications/Xcode_16.2.app/Contents/Developer/Platforms/
|
||||
ls /Applications/Xcode_16.2.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs
|
||||
make TARGET=ARMV8 DYNAMIC_ARCH=1 NUM_THREADS=32 HOSTCC=clang NOFORTRAN=1
|
||||
|
||||
- job: OSX_IOS_ARMV7
|
||||
pool:
|
||||
vmImage: 'macOS-13'
|
||||
vmImage: 'macOS-14'
|
||||
variables:
|
||||
CC: /Applications/Xcode_14.2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
|
||||
CFLAGS: -O2 -mno-thumb -Wno-macro-redefined -isysroot /Applications/Xcode_14.2.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk -arch armv7 -miphoneos-version-min=5.1
|
||||
CC: /Applications/Xcode_16.2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
|
||||
CFLAGS: -O2 -mno-thumb -Wno-macro-redefined -isysroot /Applications/Xcode_16.2.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.2.sdk -arch armv7 -miphoneos-version-min=5.1
|
||||
steps:
|
||||
- script: |
|
||||
make TARGET=ARMV7 DYNAMIC_ARCH=1 NUM_THREADS=32 HOSTCC=clang NOFORTRAN=1
|
||||
|
||||
- job: OSX_xbuild_DYNAMIC_ARM64
|
||||
pool:
|
||||
vmImage: 'macOS-13'
|
||||
vmImage: 'macOS-14'
|
||||
variables:
|
||||
CC: /Applications/Xcode_14.2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
|
||||
CFLAGS: -O2 -Wno-macro-redefined -isysroot /Applications/Xcode_14.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk -arch arm64
|
||||
CC: /Applications/Xcode_16.2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
|
||||
CFLAGS: -O2 -Wno-macro-redefined -isysroot /Applications/Xcode_16.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.2.sdk -arch arm64
|
||||
steps:
|
||||
- script: |
|
||||
ls /Applications/Xcode_14.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
|
||||
ls /Applications/Xcode_16.2.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
|
||||
/Applications/Xcode_12.2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch arm64 --print-supported-cpus
|
||||
/Applications/Xcode_14.2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang --version
|
||||
/Applications/Xcode_16.2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang --version
|
||||
make TARGET=ARMV8 DYNAMIC_ARCH=1 NUM_THREADS=32 HOSTCC=clang NOFORTRAN=1
|
||||
|
||||
- job: ALPINE_MUSL
|
||||
|
||||
@@ -335,7 +335,14 @@ if [ "$architecture" = "arm64" ]; then
|
||||
fi
|
||||
|
||||
no_sme=0
|
||||
is_appleclang=0
|
||||
if [ "$architecture" = "arm64" ]; then
|
||||
if [ "$compiler" = "CLANG" ]; then
|
||||
data=`$compiler_name --version`
|
||||
case "$data" in Apple*)
|
||||
is_appleclang=1
|
||||
esac
|
||||
fi
|
||||
tmpd=$(mktemp -d 2>/dev/null || mktemp -d -t 'OBC')
|
||||
tmpf="$tmpd/a.S"
|
||||
printf ".text \n.global sme_test\n\nsme_test:\nsmstart\nsmstop\nret\n">> "$tmpf"
|
||||
@@ -469,6 +476,7 @@ done
|
||||
[ "$no_avx512bf" -eq 1 ] && printf "NO_AVX512BF16=1\n"
|
||||
[ "$no_avx2" -eq 1 ] && printf "NO_AVX2=1\n"
|
||||
[ "$oldgcc" -eq 1 ] && printf "OLDGCC=1\n"
|
||||
[ "$is_appleclang" -eq 1 ] && printf "APPLECLANG=1\n"
|
||||
exit 0
|
||||
}
|
||||
|
||||
@@ -499,6 +507,7 @@ done
|
||||
[ "$no_avx512bf" -eq 1 ] && printf "NO_AVX512BF16=1\n"
|
||||
[ "$no_avx2" -eq 1 ] && printf "NO_AVX2=1\n"
|
||||
[ "$oldgcc" -eq 1 ] && printf "OLDGCC=1\n"
|
||||
[ "$is_appleclang" -eq 1 ] && printf "APPLECLANG=1\n"
|
||||
[ "$no_lsx" -eq 1 ] && printf "NO_LSX=1\n"
|
||||
[ "$no_lasx" -eq 1 ] && printf "NO_LASX=1\n"
|
||||
} >> "$makefile"
|
||||
|
||||
@@ -456,6 +456,14 @@ void cblas_cgemm_batch(OPENBLAS_CONST enum CBLAS_ORDER Order, OPENBLAS_CONST enu
|
||||
void cblas_zgemm_batch(OPENBLAS_CONST enum CBLAS_ORDER Order, OPENBLAS_CONST enum CBLAS_TRANSPOSE * TransA_array, OPENBLAS_CONST enum CBLAS_TRANSPOSE * TransB_array, OPENBLAS_CONST blasint * M_array, OPENBLAS_CONST blasint * N_array, OPENBLAS_CONST blasint * K_array,
|
||||
OPENBLAS_CONST void * alpha_array, OPENBLAS_CONST void ** A_array, OPENBLAS_CONST blasint * lda_array, OPENBLAS_CONST void ** B_array, OPENBLAS_CONST blasint * ldb_array, OPENBLAS_CONST void * beta_array, void ** C_array, OPENBLAS_CONST blasint * ldc_array, OPENBLAS_CONST blasint group_count, OPENBLAS_CONST blasint * group_size);
|
||||
|
||||
void cblas_sgemm_batch_strided(OPENBLAS_CONST enum CBLAS_ORDER Order, OPENBLAS_CONST enum CBLAS_TRANSPOSE TransA, OPENBLAS_CONST enum CBLAS_TRANSPOSE TransB, OPENBLAS_CONST blasint M, OPENBLAS_CONST blasint N, OPENBLAS_CONST blasint K, OPENBLAS_CONST float alpha, OPENBLAS_CONST float * A, OPENBLAS_CONST blasint lda, OPENBLAS_CONST blasint stridea, OPENBLAS_CONST float * B, OPENBLAS_CONST blasint ldb, OPENBLAS_CONST blasint strideb, OPENBLAS_CONST float beta, float * C, OPENBLAS_CONST blasint ldc, OPENBLAS_CONST blasint stridec, OPENBLAS_CONST blasint group_size);
|
||||
|
||||
void cblas_dgemm_batch_strided(OPENBLAS_CONST enum CBLAS_ORDER Order, OPENBLAS_CONST enum CBLAS_TRANSPOSE TransA, OPENBLAS_CONST enum CBLAS_TRANSPOSE TransB, OPENBLAS_CONST blasint M, OPENBLAS_CONST blasint N, OPENBLAS_CONST blasint K, OPENBLAS_CONST double alpha, OPENBLAS_CONST double * A, OPENBLAS_CONST blasint lda, OPENBLAS_CONST blasint stridea, OPENBLAS_CONST double * B, OPENBLAS_CONST blasint ldb, OPENBLAS_CONST blasint strideb, OPENBLAS_CONST double beta, double * C, OPENBLAS_CONST blasint ldc, OPENBLAS_CONST blasint stridec, OPENBLAS_CONST blasint group_size);
|
||||
|
||||
void cblas_cgemm_batch_strided(OPENBLAS_CONST enum CBLAS_ORDER Order, OPENBLAS_CONST enum CBLAS_TRANSPOSE TransA, OPENBLAS_CONST enum CBLAS_TRANSPOSE TransB, OPENBLAS_CONST blasint M, OPENBLAS_CONST blasint N, OPENBLAS_CONST blasint K, OPENBLAS_CONST void * alpha, OPENBLAS_CONST void * A, OPENBLAS_CONST blasint lda, OPENBLAS_CONST blasint stridea, OPENBLAS_CONST void * B, OPENBLAS_CONST blasint ldb, OPENBLAS_CONST blasint strideb, OPENBLAS_CONST void * beta, void * C, OPENBLAS_CONST blasint ldc, OPENBLAS_CONST blasint stridec, OPENBLAS_CONST blasint group_size);
|
||||
|
||||
void cblas_zgemm_batch_strided(OPENBLAS_CONST enum CBLAS_ORDER Order, OPENBLAS_CONST enum CBLAS_TRANSPOSE TransA, OPENBLAS_CONST enum CBLAS_TRANSPOSE TransB, OPENBLAS_CONST blasint M, OPENBLAS_CONST blasint N, OPENBLAS_CONST blasint K, OPENBLAS_CONST void * alpha, OPENBLAS_CONST void * A, OPENBLAS_CONST blasint lda, OPENBLAS_CONST blasint stridea, OPENBLAS_CONST void * B, OPENBLAS_CONST blasint ldb, OPENBLAS_CONST blasint strideb, OPENBLAS_CONST void * beta, void * C, OPENBLAS_CONST blasint ldc, OPENBLAS_CONST blasint stridec, OPENBLAS_CONST blasint group_size);
|
||||
|
||||
/*** BFLOAT16 and INT8 extensions ***/
|
||||
/* convert float array to BFLOAT16 array by rounding */
|
||||
void cblas_sbstobf16(OPENBLAS_CONST blasint n, OPENBLAS_CONST float *in, OPENBLAS_CONST blasint incin, bfloat16 *out, OPENBLAS_CONST blasint incout);
|
||||
@@ -477,6 +485,7 @@ void cblas_sbgemm(OPENBLAS_CONST enum CBLAS_ORDER Order, OPENBLAS_CONST enum C
|
||||
void cblas_sbgemm_batch(OPENBLAS_CONST enum CBLAS_ORDER Order, OPENBLAS_CONST enum CBLAS_TRANSPOSE * TransA_array, OPENBLAS_CONST enum CBLAS_TRANSPOSE * TransB_array, OPENBLAS_CONST blasint * M_array, OPENBLAS_CONST blasint * N_array, OPENBLAS_CONST blasint * K_array,
|
||||
OPENBLAS_CONST float * alpha_array, OPENBLAS_CONST bfloat16 ** A_array, OPENBLAS_CONST blasint * lda_array, OPENBLAS_CONST bfloat16 ** B_array, OPENBLAS_CONST blasint * ldb_array, OPENBLAS_CONST float * beta_array, float ** C_array, OPENBLAS_CONST blasint * ldc_array, OPENBLAS_CONST blasint group_count, OPENBLAS_CONST blasint * group_size);
|
||||
|
||||
void cblas_sbgemm_batch_strided(OPENBLAS_CONST enum CBLAS_ORDER Order, OPENBLAS_CONST enum CBLAS_TRANSPOSE TransA, OPENBLAS_CONST enum CBLAS_TRANSPOSE TransB, OPENBLAS_CONST blasint M, OPENBLAS_CONST blasint N, OPENBLAS_CONST blasint K, OPENBLAS_CONST float alpha, OPENBLAS_CONST bfloat16 * A, OPENBLAS_CONST blasint lda, OPENBLAS_CONST blasint stridea, OPENBLAS_CONST bfloat16 * B, OPENBLAS_CONST blasint ldb, OPENBLAS_CONST blasint strideb, OPENBLAS_CONST float beta, float * C, OPENBLAS_CONST blasint ldc, OPENBLAS_CONST blasint stridec, OPENBLAS_CONST blasint group_size);
|
||||
/*** FLOAT16 extensions ***/
|
||||
void cblas_shgemm(OPENBLAS_CONST enum CBLAS_ORDER Order, OPENBLAS_CONST enum CBLAS_TRANSPOSE TransA, OPENBLAS_CONST enum CBLAS_TRANSPOSE TransB, OPENBLAS_CONST blasint M, OPENBLAS_CONST blasint N, OPENBLAS_CONST blasint K,
|
||||
OPENBLAS_CONST float alpha, OPENBLAS_CONST hfloat16 *A, OPENBLAS_CONST blasint lda, OPENBLAS_CONST hfloat16 *B, OPENBLAS_CONST blasint ldb, OPENBLAS_CONST float beta, float *C, OPENBLAS_CONST blasint ldc);
|
||||
|
||||
@@ -50,30 +50,30 @@ set(PN OpenBLAS)
|
||||
|
||||
# need to check that the @USE_*@ evaluate to something cmake can perform boolean logic upon
|
||||
if(@USE_OPENMP@)
|
||||
set(${PN}_openmp_FOUND 1)
|
||||
set(${PN}@SUFFIX64@_openmp_FOUND 1)
|
||||
elseif(@USE_THREAD@)
|
||||
set(${PN}_pthread_FOUND 1)
|
||||
set(${PN}@SUFFIX64@_pthread_FOUND 1)
|
||||
else()
|
||||
set(${PN}_serial_FOUND 1)
|
||||
set(${PN}@SUFFIX64@_serial_FOUND 1)
|
||||
endif()
|
||||
|
||||
check_required_components(${PN})
|
||||
check_required_components(${PN}@SUFFIX64@)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Don't include targets if this file is being picked up by another
|
||||
# project which has already built this as a subproject
|
||||
#-----------------------------------------------------------------------------
|
||||
if(NOT TARGET ${PN}::OpenBLAS)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/${PN}Targets.cmake")
|
||||
if(NOT TARGET ${PN}@SUFFIX64@::OpenBLAS)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/${PN}@SUFFIX64@Targets.cmake")
|
||||
|
||||
get_property(_loc TARGET ${PN}::OpenBLAS PROPERTY LOCATION)
|
||||
set(${PN}_LIBRARY ${_loc})
|
||||
get_property(_ill TARGET ${PN}::OpenBLAS PROPERTY INTERFACE_LINK_LIBRARIES)
|
||||
set(${PN}_LIBRARIES ${_ill})
|
||||
get_property(_loc TARGET ${PN}@SUFFIX64@::OpenBLAS PROPERTY LOCATION)
|
||||
set(${PN}@SUFFIX64@_LIBRARY ${_loc})
|
||||
get_property(_ill TARGET ${PN}@SUFFIX64@::OpenBLAS PROPERTY INTERFACE_LINK_LIBRARIES)
|
||||
set(${PN}@SUFFIX64@_LIBRARIES ${_ill})
|
||||
|
||||
get_property(_id TARGET ${PN}::OpenBLAS PROPERTY INCLUDE_DIRECTORIES)
|
||||
set(${PN}_INCLUDE_DIR ${_id})
|
||||
get_property(_iid TARGET ${PN}::OpenBLAS PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
|
||||
set(${PN}_INCLUDE_DIRS ${_iid})
|
||||
get_property(_id TARGET ${PN}@SUFFIX64@::OpenBLAS PROPERTY INCLUDE_DIRECTORIES)
|
||||
set(${PN}@SUFFIX64@_INCLUDE_DIR ${_id})
|
||||
get_property(_iid TARGET ${PN}@SUFFIX64@::OpenBLAS PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
|
||||
set(${PN}@SUFFIX64@_INCLUDE_DIRS ${_iid})
|
||||
endif()
|
||||
|
||||
|
||||
+5
-2
@@ -40,13 +40,16 @@ if (DYNAMIC_ARCH)
|
||||
endif ()
|
||||
if (${CMAKE_C_COMPILER_VERSION} VERSION_GREATER_EQUAL 14) # SME ACLE supported in GCC >= 14
|
||||
set(DYNAMIC_CORE ${DYNAMIC_CORE} ARMV9SME)
|
||||
endif()
|
||||
if (${CMAKE_C_COMPILER_ID} MATCHES "Clang" AND ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
|
||||
set(DYNAMIC_CORE ${DYNAMIC_CORE} VORTEXM4)
|
||||
endif()
|
||||
elseif (${CMAKE_C_COMPILER_ID} MATCHES "Clang")
|
||||
if (${CMAKE_C_COMPILER_VERSION} VERSION_GREATER_EQUAL 11) # SVE ACLE supported in LLVM >= 11
|
||||
set(DYNAMIC_CORE ${DYNAMIC_CORE} NEOVERSEV1 NEOVERSEN2 ARMV8SVE A64FX)
|
||||
endif ()
|
||||
if (${CMAKE_C_COMPILER_VERSION} VERSION_GREATER_EQUAL 19) # SME ACLE supported in LLVM >= 19
|
||||
set(DYNAMIC_CORE ${DYNAMIC_CORE} ARMV9SME)
|
||||
if (${CMAKE_C_COMPILER_VERSION} VERSION_GREATER_EQUAL 19 OR (${CMAKE_C_COMPILER_ID} MATCHES AppleClang AND ${CMAKE_C_COMPILER_VERSION} VERSION_GREATER_EQUAL 17) ) # SME ACLE supported in LLVM >= 19 and AppleClang >= 17
|
||||
set(DYNAMIC_CORE ${DYNAMIC_CORE} ARMV9SME VORTEXM4)
|
||||
endif()
|
||||
endif ()
|
||||
if (DYNAMIC_LIST)
|
||||
|
||||
+49
-8
@@ -213,7 +213,7 @@ endif ()
|
||||
|
||||
if (${CORE} STREQUAL A64FX)
|
||||
if (NOT DYNAMIC_ARCH)
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "NVC" AND NOT NO_SVE)
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "NVHPC" AND NOT NO_SVE)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -tp=a64fx")
|
||||
elseif (${GCC_VERSION} VERSION_GREATER 11.0 OR ${GCC_VERSION} VERSION_EQUAL 11.0)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -march=armv8.2-a+sve -mtune=a64fx")
|
||||
@@ -227,7 +227,7 @@ if (${CORE} STREQUAL NEOVERSEV2)
|
||||
if (NOT DYNAMIC_ARCH)
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "PGI" AND NOT NO_SVE)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -Msve_intrinsics -march=armv8.5-a+sve+sve2+bf16 -mtune=neoverse-v2")
|
||||
elseif (${CMAKE_C_COMPILER_ID} STREQUAL "NVC" AND NOT NO_SVE)
|
||||
elseif (${CMAKE_C_COMPILER_ID} STREQUAL "NVHPC" AND NOT NO_SVE)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -tp=neoverse-v2")
|
||||
else ()
|
||||
if (${GCC_VERSION} VERSION_GREATER 13.0 OR ${GCC_VERSION} VERSION_EQUAL 13.0)
|
||||
@@ -245,7 +245,7 @@ if (${CORE} STREQUAL NEOVERSEN2)
|
||||
if (NOT DYNAMIC_ARCH)
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "PGI" AND NOT NO_SVE)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -Msve_intrinsics -march=armv8.5-a+sve+sve2+bf16 -mtune=neoverse-n2")
|
||||
elseif (${CMAKE_C_COMPILER_ID} STREQUAL "NVC" AND NOT NO_SVE)
|
||||
elseif (${CMAKE_C_COMPILER_ID} STREQUAL "NVHPC" AND NOT NO_SVE)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -tp=neoverse-v2")
|
||||
else ()
|
||||
if (${GCC_VERSION} VERSION_GREATER 11.1 OR ${GCC_VERSION} VERSION_EQUAL 11.1)
|
||||
@@ -261,7 +261,7 @@ if (${CORE} STREQUAL NEOVERSEV1)
|
||||
if (NOT DYNAMIC_ARCH)
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "PGI" AND NOT NO_SVE)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -Msve_intrinsics -march=armv8.4-a+sve+bf16 -mtune=neoverse-v1")
|
||||
elseif (${CMAKE_C_COMPILER_ID} STREQUAL "NVC" AND NOT NO_SVE)
|
||||
elseif (${CMAKE_C_COMPILER_ID} STREQUAL "NVHPC" AND NOT NO_SVE)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -tp=neoverse-v1")
|
||||
else ()
|
||||
if (${GCC_VERSION} VERSION_GREATER 10.4 OR ${GCC_VERSION} VERSION_EQUAL 10.4)
|
||||
@@ -275,7 +275,7 @@ endif ()
|
||||
|
||||
if (${CORE} STREQUAL NEOVERSEN1)
|
||||
if (NOT DYNAMIC_ARCH)
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "NVC" AND NOT NO_SVE)
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "NVHPC" AND NOT NO_SVE)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -tp=neoverse-n1")
|
||||
elseif (${GCC_VERSION} VERSION_GREATER 9.4 OR ${GCC_VERSION} VERSION_EQUAL 9.4)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -march=armv8.2-a -mtune=neoverse-n1")
|
||||
@@ -287,7 +287,7 @@ endif ()
|
||||
|
||||
if (${CORE} STREQUAL AMPEREONE)
|
||||
if (NOT DYNAMIC_ARCH)
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "NVC")
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "NVHPC")
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -tp=neoverse-n1")
|
||||
elseif (${GCC_VERSION} VERSION_GREATER 12.1)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -march=armv8.6-a+crypto+crc+fp16+sha3+rng -mtune=ampereone")
|
||||
@@ -301,7 +301,7 @@ if (${CORE} STREQUAL ARMV8SVE)
|
||||
if (NOT DYNAMIC_ARCH)
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "PGI" AND NOT NO_SVE)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -Msve_intrinsics -march=armv8-a+sve")
|
||||
elseif (${CMAKE_C_COMPILER_ID} STREQUAL "NVC" AND NOT NO_SVE)
|
||||
elseif (${CMAKE_C_COMPILER_ID} STREQUAL "NVHPC" AND NOT NO_SVE)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -tp=host")
|
||||
else ()
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -march=armv8-a+sve")
|
||||
@@ -311,11 +311,28 @@ endif ()
|
||||
|
||||
if (${CORE} STREQUAL ARMV9SME)
|
||||
if (NOT DYNAMIC_ARCH)
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "NVC" AND NOT NO_SVE)
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "NVHPC" AND NOT NO_SVE)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -tp=host")
|
||||
else ()
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -march=armv9-a+sme")
|
||||
if (${OSNAME} STREQUAL Windows AND ${CMAKE_C_COMPILER_ID} MATCHES "Clang" )
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} --aarch64-stack-hazard-size=0")
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (${CORE} STREQUAL VORTEXM4)
|
||||
if (NOT DYNAMIC_ARCH)
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "NVC" AND NOT NO_SVE)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -tp=host")
|
||||
else ()
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "AppleClang")
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -march=armv8.4-a+sme -mcpu=apple-m4")
|
||||
else ()
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -march=armv8.4-a -mcpu=apple-m4")
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
@@ -391,6 +408,30 @@ if (${CORE} STREQUAL PPCG4)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
||||
if ((${CORE} STREQUAL RISCV64_ZVL128B) OR (${CORE} STREQUAL RISCV64_ZVL256B))
|
||||
set (RISCV64_OPT "rv64imafdcv")
|
||||
if (BUILD_BFLOAT16)
|
||||
set (RISCV64_OPT "${RISCV64_OPT}_zvfbfwma")
|
||||
endif()
|
||||
if (BUILD_HFLOAT16)
|
||||
set (RISCV64_OPT "${RISCV64_OPT}_zvfh_zfh")
|
||||
endif()
|
||||
if (${CORE} STREQUAL RISCV64_ZVL256B)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -march=${RISCV64_OPT}_zvl256b -mabi=lp64d")
|
||||
endif()
|
||||
if (${CORE} STREQUAL RISCV64_ZVL128B)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -march=${RISCV64_OPT}_zvl128b -mabi=lp64d")
|
||||
endif()
|
||||
endif()
|
||||
if (${CORE} STREQUAL RISCV64_GENERIC)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -march=rv64imafdc -mabi=lp64d")
|
||||
endif()
|
||||
if (${CORE} STREQUAL x280)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -march=rv64imafdcv_zba_zbb_zfh_zvl512b -mabi=lp64d")
|
||||
endif()
|
||||
|
||||
|
||||
if (NOT DYNAMIC_ARCH)
|
||||
if (HAVE_AVX2)
|
||||
set (CCOMMON_OPT "${CCOMMON_OPT} -mavx2")
|
||||
|
||||
+20
-1
@@ -175,6 +175,10 @@ if (BUILD_BFLOAT16)
|
||||
SetFallback(SBGEMVNKERNEL ../x86_64/sbgemv_n.c)
|
||||
SetFallback(SBGEMVTKERNEL ../x86_64/sbgemv_t.c)
|
||||
endif ()
|
||||
if (BUILD_HFLOAT16)
|
||||
SetFallback(SHGEMVNKERNEL ../generic/gemv_n.c)
|
||||
SetFallback(SHGEMVTKERNEL ../generic/gemv_t.c)
|
||||
endif ()
|
||||
endmacro ()
|
||||
|
||||
macro(SetDefaultL2)
|
||||
@@ -228,6 +232,10 @@ if (BUILD_BFLOAT16)
|
||||
SetFallback(BGEMVTKERNEL ../generic/gemv_t.c)
|
||||
SetFallback(SBGEMVNKERNEL ../x86_64/sbgemv_n.c)
|
||||
SetFallback(SBGEMVTKERNEL ../x86_64/sbgemv_t.c)
|
||||
endif ()
|
||||
if (BUILD_HFLOAT16)
|
||||
SetFallback(SHGEMVNKERNEL ../generic/gemv_n.c)
|
||||
SetFallback(SHGEMVTKERNEL ../generic/gemv_t.c)
|
||||
SetFallback(SHGERKERNEL ../generic/ger.c)
|
||||
endif ()
|
||||
endmacro ()
|
||||
@@ -260,5 +268,16 @@ if (BUILD_BFLOAT16)
|
||||
SetFallback(SBGEMMONCOPYOBJ sbgemm_oncopy.o)
|
||||
SetFallback(SBGEMMOTCOPYOBJ sbgemm_otcopy.o)
|
||||
endif ()
|
||||
|
||||
if (BUILD_HFLOAT16)
|
||||
SetFallback(SHGEMMKERNEL ../generic/gemmkernel_2x2.c)
|
||||
SetFallback(SHGEMM_BETA ../generic/gemm_beta.c)
|
||||
SetFallback(SHGEMMINCOPY ../generic/gemm_ncopy_2.c)
|
||||
SetFallback(SHGEMMITCOPY ../generic/gemm_tcopy_2.c)
|
||||
SetFallback(SHGEMMONCOPY ../generic/gemm_ncopy_2.c)
|
||||
SetFallback(SHGEMMOTCOPY ../generic/gemm_tcopy_2.c)
|
||||
SetFallback(SHGEMMINCOPYOBJ shgemm_incopy.o)
|
||||
SetFallback(SHGEMMITCOPYOBJ shgemm_itcopy.o)
|
||||
SetFallback(SHGEMMONCOPYOBJ shgemm_oncopy.o)
|
||||
SetFallback(SHGEMMOTCOPYOBJ shgemm_otcopy.o)
|
||||
endif ()
|
||||
endmacro ()
|
||||
|
||||
@@ -99,7 +99,6 @@ if (${COMPILER_ID} STREQUAL "GNU")
|
||||
endif ()
|
||||
|
||||
string(TOUPPER ${ARCH} UC_ARCH)
|
||||
|
||||
file(WRITE ${TARGET_CONF_TEMP}
|
||||
"#define OS_${HOST_OS}\t1\n"
|
||||
"#define ARCH_${UC_ARCH}\t1\n"
|
||||
@@ -111,6 +110,10 @@ if (${HOST_OS} STREQUAL "WINDOWSSTORE")
|
||||
file(APPEND ${TARGET_CONF_TEMP}
|
||||
"#define OS_WINNT\t1\n")
|
||||
endif ()
|
||||
if (${HOST_OS} STREQUAL CYGWIN)
|
||||
file(APPEND ${TARGET_CONF_TEMP}
|
||||
"#define OS_CYGWIN_NT\t1\n")
|
||||
endif ()
|
||||
|
||||
# f_check
|
||||
if (NOT NOFORTRAN)
|
||||
@@ -1252,7 +1255,7 @@ endif ()
|
||||
set(ZGEMM_UNROLL_M 4)
|
||||
set(ZGEMM_UNROLL_N 4)
|
||||
set(SYMV_P 16)
|
||||
elseif ("${TCORE}" STREQUAL "VORTEX")
|
||||
elseif ("${TCORE}" STREQUAL "VORTEX" OR "${TCORE}" STREQUAL "VORTEXM4")
|
||||
file(APPEND ${TARGET_CONF_TEMP}
|
||||
"#define ARMV8\n"
|
||||
"#define L1_CODE_SIZE\t32768\n"
|
||||
@@ -1636,6 +1639,8 @@ else(NOT CMAKE_CROSSCOMPILING)
|
||||
unset (HAVE_VFP)
|
||||
unset (HAVE_VFPV3)
|
||||
unset (HAVE_VFPV4)
|
||||
unset (HAVE_SVE)
|
||||
unset (HAVE_SME)
|
||||
message(STATUS "Running getarch")
|
||||
|
||||
# use the cmake binary w/ the -E param to run a shell command in a cross-platform way
|
||||
|
||||
+41
-4
@@ -367,6 +367,15 @@ if (${TARGET} STREQUAL NEOVERSEV1)
|
||||
endif()
|
||||
if (${TARGET} STREQUAL ARMV9SME)
|
||||
set (KERNEL_DEFINITIONS "${KERNEL_DEFINITIONS} -march=armv9-a+sme -O3")
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL Windows AND ${CMAKE_C_COMPILER_ID} MATCHES "Clang")
|
||||
set (KERNEL_DEFINITIONS "${KERNEL_DEFINITIONS} --aarch64-stack-hazard-size=0")
|
||||
endif()
|
||||
endif()
|
||||
if (${TARGET} STREQUAL VORTEXM4)
|
||||
set (KERNEL_DEFINITIONS "${KERNEL_DEFINITIONS} -march=armv8.4-a+sme -O3")
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL Windows AND ${CMAKE_C_COMPILER_ID} MATCHES "Clang")
|
||||
set (KERNEL_DEFINITIONS "${KERNEL_DEFINITIONS} --aarch64-stack-hazard-size=0")
|
||||
endif()
|
||||
endif()
|
||||
if (${TARGET} STREQUAL A64FX)
|
||||
if (${CMAKE_C_COMPILER_ID} STREQUAL "PGI" AND NOT NO_SVE)
|
||||
@@ -381,6 +390,28 @@ if (${TARGET} STREQUAL NEOVERSEV1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ((${TARGET} STREQUAL RISCV64_ZVL128B) OR (${TARGET} STREQUAL RISCV64_ZVL256B))
|
||||
set (RISCV64_OPT "rv64imafdcv")
|
||||
if (BUILD_BFLOAT16)
|
||||
set (RISCV64_OPT "${RISCV64_OPT}_zvfbfwma")
|
||||
endif()
|
||||
if (BUILD_HFLOAT16)
|
||||
set (RISCV64_OPT "${RISCV64_OPT}_zvfh_zfh")
|
||||
endif()
|
||||
if (${TARGET} STREQUAL RISCV64_ZVL256B)
|
||||
set (KERNEL_DEFINITIONS "${KERNEL_DEFINITIONS} -march=${RISCV64_OPT}_zvl256b -mabi=lp64d")
|
||||
endif()
|
||||
if (${TARGET} STREQUAL RISCV64_ZVL128B)
|
||||
set (KERNEL_DEFINITIONS "${KERNEL_DEFINITIONS} -march=${RISCV64_OPT}_zvl128b -mabi=lp64d")
|
||||
endif()
|
||||
endif()
|
||||
if (${TARGET} STREQUAL RISCV64_GENERIC)
|
||||
set (KERNEL_DEFINITIONS "${KERNEL_DEFINITIONS} -march=rv64imafdc -mabi=lp64d")
|
||||
endif()
|
||||
if (${TARGET} STREQUAL x280)
|
||||
set (KERNEL_DEFINITIONS "${KERNEL_DEFINITIONS} -march=rv64imafdcv_zba_zbb_zfh_zvl512b -mabi=lp64d")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if (DEFINED BINARY)
|
||||
@@ -425,10 +456,16 @@ if (USE_OPENMP)
|
||||
if (NOT NOFORTRAN)
|
||||
find_package(OpenMP COMPONENTS Fortran REQUIRED)
|
||||
# Avoid mixed OpenMP linkage
|
||||
get_target_property(OMP_C_LIB OpenMP::OpenMP_C INTERFACE_LINK_LIBRARIES)
|
||||
get_target_property(OMP_Fortran_LIB OpenMP::OpenMP_Fortran INTERFACE_LINK_LIBRARIES)
|
||||
if (NOT OMP_C_LIB STREQUAL OMP_Fortran_LIB)
|
||||
message(FATAL_ERROR "Multiple OpenMP runtime libraries detected. Mixed OpenMP runtime linkage is dangerous. You may pass -DOpenMP_LANG_LIB_NAMES and -DOpenMP_omp_LIBRARY to manually choose the OpenMP library.")
|
||||
get_target_property(OMP_C_LIBS OpenMP::OpenMP_C INTERFACE_LINK_LIBRARIES)
|
||||
get_target_property(OMP_F_LIBS OpenMP::OpenMP_Fortran INTERFACE_LINK_LIBRARIES)
|
||||
if (NOT OMP_C_LIBS STREQUAL OMP_F_LIBS)
|
||||
message(NOTICE
|
||||
"CMake detected different OpenMP libraries for C and Fortran:\n"
|
||||
"C=${OMP_C_LIBS}\n"
|
||||
"Fortran=${OMP_F_LIBS}\n"
|
||||
"In case you encounter issues, please check that this is correct.\n"
|
||||
"You may pass -DOpenMP_<lang>_LIB_NAMES and -DOpenMP_<libname>_LIBRARY to cmake to manually force the OpenMP library."
|
||||
)
|
||||
endif()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
+9
-3
@@ -375,9 +375,12 @@ function(GenerateNamedObjects sources_in)
|
||||
if (NOT no_float_type)
|
||||
string(SUBSTRING ${float_type} 0 1 float_char)
|
||||
string(TOLOWER ${float_char} float_char)
|
||||
if (${float_type} STREQUAL "BFLOAT16" AND NOT "${defines_in}" MATCHES "BGEM")
|
||||
set (float_char "sb")
|
||||
endif ()
|
||||
if (${float_type} STREQUAL "BFLOAT16" AND NOT "${defines_in}" MATCHES "BGEM")
|
||||
set (float_char "sb")
|
||||
endif ()
|
||||
if (${float_type} STREQUAL "HFLOAT16" AND NOT "${defines_in}" MATCHES "HGEM")
|
||||
set (float_char "sh")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (NOT name_in)
|
||||
@@ -427,6 +430,9 @@ function(GenerateNamedObjects sources_in)
|
||||
endif ()
|
||||
if (${float_type} STREQUAL "BFLOAT16")
|
||||
list(APPEND obj_defines "BFLOAT16")
|
||||
endif ()
|
||||
if (${float_type} STREQUAL "HFLOAT16")
|
||||
list(APPEND obj_defines "HFLOAT16")
|
||||
endif ()
|
||||
if (${float_type} STREQUAL "COMPLEX" OR ${float_type} STREQUAL "ZCOMPLEX")
|
||||
list(APPEND obj_defines "COMPLEX")
|
||||
|
||||
@@ -362,18 +362,6 @@ typedef int blasint;
|
||||
#define MAX_CPU_NUMBER 2
|
||||
#endif
|
||||
|
||||
#if defined(OS_SUNOS)
|
||||
#define YIELDING thr_yield()
|
||||
#endif
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define YIELDING YieldProcessor()
|
||||
#else
|
||||
#define YIELDING SwitchToThread()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(ARMV7) || defined(ARMV6) || defined(ARMV8) || defined(ARMV5)
|
||||
#define YIELDING __asm__ __volatile__ ("nop;nop;nop;nop;nop;nop;nop;nop; \n");
|
||||
#endif
|
||||
@@ -398,14 +386,26 @@ typedef int blasint;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#define YIELDING
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#undef YIELDING // MSVC doesn't support assembly code
|
||||
#define YIELDING YieldProcessor()
|
||||
#endif
|
||||
|
||||
#ifndef YIELDING
|
||||
#if defined(OS_SUNOS)
|
||||
#define YIELDING thr_yield()
|
||||
|
||||
#elif defined(OS_WINDOWS)
|
||||
#define YIELDING SwitchToThread()
|
||||
|
||||
#else // assume POSIX.1-2008
|
||||
#define YIELDING sched_yield()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/***
|
||||
To alloc job_t on heap or stack.
|
||||
@@ -765,7 +765,7 @@ static __inline int readenv_atoi(char *env) {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#ifdef OS_WINDOWS
|
||||
#if defined(OS_WINDOWS) && !defined(OS_CYGWIN_NT)
|
||||
static __inline int readenv_atoi(char *env) {
|
||||
env_var_t p;
|
||||
return readenv(p,env) ? 0 : atoi(p);
|
||||
@@ -781,7 +781,7 @@ static __inline int readenv_atoi(char *env) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(XDOUBLE) || !defined(QUAD_PRECISION)
|
||||
#if !defined(BFLOAT16) && (!defined(XDOUBLE) || !defined(QUAD_PRECISION))
|
||||
|
||||
static __inline void compinv(FLOAT *b, FLOAT ar, FLOAT ai){
|
||||
|
||||
|
||||
+3
-3
@@ -114,9 +114,9 @@ static __inline BLASULONG rpcc(void){
|
||||
#else
|
||||
BLASULONG ret = 0;
|
||||
blasint shift;
|
||||
|
||||
__asm__ __volatile__ ("isb; mrs %0,cntvct_el0":"=r"(ret));
|
||||
__asm__ __volatile__ ("mrs %0,cntfrq_el0; clz %w0, %w0":"=&r"(shift));
|
||||
|
||||
__asm__ __volatile__ ("isb\n\tmrs %0,cntvct_el0":"=r"(ret));
|
||||
__asm__ __volatile__ ("mrs %x0,cntfrq_el0\n\tclz %w0, %w0":"=&r"(shift));
|
||||
|
||||
return ret << shift;
|
||||
#endif
|
||||
|
||||
@@ -261,6 +261,8 @@ void BLASFUNC(bgemv)(char *, blasint *, blasint *, bfloat16 *, bfloat16 *, blas
|
||||
bfloat16 *, blasint *, bfloat16 *, bfloat16 *, blasint *);
|
||||
void BLASFUNC(sbgemv)(char *, blasint *, blasint *, float *, bfloat16 *, blasint *,
|
||||
bfloat16 *, blasint *, float *, float *, blasint *);
|
||||
void BLASFUNC(shgemv)(char *, blasint *, blasint *, float *, hfloat16 *, blasint *,
|
||||
hfloat16 *, blasint *, float *, float *, blasint *);
|
||||
void BLASFUNC(sgemv)(char *, blasint *, blasint *, float *, float *, blasint *,
|
||||
float *, blasint *, float *, float *, blasint *);
|
||||
void BLASFUNC(dgemv)(char *, blasint *, blasint *, double *, double *, blasint *,
|
||||
|
||||
@@ -54,6 +54,10 @@ int sbgemv_n(BLASLONG, BLASLONG, float, bfloat16 *, BLASLONG, bfloat16 *, BLASLO
|
||||
int sbgemv_t(BLASLONG, BLASLONG, float, bfloat16 *, BLASLONG, bfloat16 *, BLASLONG, float, float *, BLASLONG);
|
||||
int sbgemv_thread_n(BLASLONG, BLASLONG, float, bfloat16 *, BLASLONG, bfloat16 *, BLASLONG, float, float *, BLASLONG, int);
|
||||
int sbgemv_thread_t(BLASLONG, BLASLONG, float, bfloat16 *, BLASLONG, bfloat16 *, BLASLONG, float, float *, BLASLONG, int);
|
||||
int shgemv_n(BLASLONG, BLASLONG, float, hfloat16 *, BLASLONG, hfloat16 *, BLASLONG, float, float *, BLASLONG);
|
||||
int shgemv_t(BLASLONG, BLASLONG, float, hfloat16 *, BLASLONG, hfloat16 *, BLASLONG, float, float *, BLASLONG);
|
||||
int shgemv_thread_n(BLASLONG, BLASLONG, float, hfloat16 *, BLASLONG, hfloat16 *, BLASLONG, float, float *, BLASLONG, int);
|
||||
int shgemv_thread_t(BLASLONG, BLASLONG, float, hfloat16 *, BLASLONG, hfloat16 *, BLASLONG, float, float *, BLASLONG, int);
|
||||
int sger_k (BLASLONG, BLASLONG, BLASLONG, float, float *, BLASLONG, float *, BLASLONG, float *, BLASLONG, float *);
|
||||
int dger_k (BLASLONG, BLASLONG, BLASLONG, double, double *, BLASLONG, double *, BLASLONG, double *, BLASLONG, double *);
|
||||
int qger_k (BLASLONG, BLASLONG, BLASLONG, xdouble, xdouble *, BLASLONG, xdouble *, BLASLONG, xdouble *, BLASLONG, xdouble *);
|
||||
|
||||
@@ -59,6 +59,82 @@ void sgemm_direct_alpha_beta(BLASLONG M, BLASLONG N, BLASLONG K,
|
||||
float beta,
|
||||
float * R, BLASLONG strideR);
|
||||
|
||||
void ssymm_direct_alpha_betaLU(BLASLONG M, BLASLONG N,
|
||||
float alpha,
|
||||
float * A, BLASLONG strideA,
|
||||
float * B, BLASLONG strideB,
|
||||
float beta,
|
||||
float * R, BLASLONG strideR);
|
||||
void ssymm_direct_alpha_betaLL(BLASLONG M, BLASLONG N,
|
||||
float alpha,
|
||||
float * A, BLASLONG strideA,
|
||||
float * B, BLASLONG strideB,
|
||||
float beta,
|
||||
float * R, BLASLONG strideR);
|
||||
|
||||
void strmm_direct_LNUN(BLASLONG M, BLASLONG N,
|
||||
float alpha,
|
||||
float * A, BLASLONG strideA,
|
||||
float * B, BLASLONG strideB);
|
||||
void strmm_direct_LNLN(BLASLONG M, BLASLONG N,
|
||||
float alpha,
|
||||
float * A, BLASLONG strideA,
|
||||
float * B, BLASLONG strideB);
|
||||
void strmm_direct_LTUN(BLASLONG M, BLASLONG N,
|
||||
float alpha,
|
||||
float * A, BLASLONG strideA,
|
||||
float * B, BLASLONG strideB);
|
||||
void strmm_direct_LTLN(BLASLONG M, BLASLONG N,
|
||||
float alpha,
|
||||
float * A, BLASLONG strideA,
|
||||
float * B, BLASLONG strideB);
|
||||
|
||||
void ssyrk_direct_alpha_betaUN(BLASLONG N, BLASLONG K,
|
||||
float alpha,
|
||||
float * A, BLASLONG strideA,
|
||||
float beta,
|
||||
float * C, BLASLONG strideC);
|
||||
void ssyrk_direct_alpha_betaUT(BLASLONG N, BLASLONG K,
|
||||
float alpha,
|
||||
float * A, BLASLONG strideA,
|
||||
float beta,
|
||||
float * C, BLASLONG strideC);
|
||||
void ssyrk_direct_alpha_betaLN(BLASLONG N, BLASLONG K,
|
||||
float alpha,
|
||||
float * A, BLASLONG strideA,
|
||||
float beta,
|
||||
float * C, BLASLONG strideC);
|
||||
void ssyrk_direct_alpha_betaLT(BLASLONG N, BLASLONG K,
|
||||
float alpha,
|
||||
float * A, BLASLONG strideA,
|
||||
float beta,
|
||||
float * C, BLASLONG strideC);
|
||||
|
||||
void ssyr2k_direct_alpha_betaUN(BLASLONG N, BLASLONG K,
|
||||
float alpha,
|
||||
float * A, BLASLONG strideA,
|
||||
float * B, BLASLONG strideB,
|
||||
float beta,
|
||||
float * R, BLASLONG strideR);
|
||||
void ssyr2k_direct_alpha_betaUT(BLASLONG N, BLASLONG K,
|
||||
float alpha,
|
||||
float * A, BLASLONG strideA,
|
||||
float * B, BLASLONG strideB,
|
||||
float beta,
|
||||
float * R, BLASLONG strideR);
|
||||
void ssyr2k_direct_alpha_betaLN(BLASLONG N, BLASLONG K,
|
||||
float alpha,
|
||||
float * A, BLASLONG strideA,
|
||||
float * B, BLASLONG strideB,
|
||||
float beta,
|
||||
float * R, BLASLONG strideR);
|
||||
void ssyr2k_direct_alpha_betaLT(BLASLONG N, BLASLONG K,
|
||||
float alpha,
|
||||
float * A, BLASLONG strideA,
|
||||
float * B, BLASLONG strideB,
|
||||
float beta,
|
||||
float * R, BLASLONG strideR);
|
||||
|
||||
int sgemm_direct_performant(BLASLONG M, BLASLONG N, BLASLONG K);
|
||||
|
||||
int shgemm_beta(BLASLONG, BLASLONG, BLASLONG, float,
|
||||
|
||||
@@ -703,6 +703,9 @@
|
||||
#define GEMM_THREAD_RC SHGEMM_THREAD_NT
|
||||
#define GEMM_THREAD_RR SHGEMM_THREAD_NN
|
||||
|
||||
#define SCAL_K SSCAL_K
|
||||
#define GEMV_N SHGEMV_N_K
|
||||
#define GEMV_T SHGEMV_T_K
|
||||
|
||||
#elif defined(BFLOAT16) && defined(BGEMM)
|
||||
#define SCAL_K BSCAL_K
|
||||
|
||||
+17
-1
@@ -60,7 +60,8 @@ int (*shgemm_itcopy )(BLASLONG, BLASLONG, hfloat16 *, BLASLONG, hfloat16 *);
|
||||
int (*shgemm_oncopy )(BLASLONG, BLASLONG, hfloat16 *, BLASLONG, hfloat16 *);
|
||||
int (*shgemm_otcopy )(BLASLONG, BLASLONG, hfloat16 *, BLASLONG, hfloat16 *);
|
||||
|
||||
|
||||
int (*shgemv_n) (BLASLONG, BLASLONG, float, hfloat16 *, BLASLONG, hfloat16 *, BLASLONG, float, float *, BLASLONG);
|
||||
int (*shgemv_t) (BLASLONG, BLASLONG, float, hfloat16 *, BLASLONG, hfloat16 *, BLASLONG, float, float *, BLASLONG);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -256,7 +257,22 @@ int (*shgemm_otcopy )(BLASLONG, BLASLONG, hfloat16 *, BLASLONG, hfloat16 *);
|
||||
#endif
|
||||
#ifdef ARCH_ARM64
|
||||
void (*sgemm_direct) (BLASLONG, BLASLONG, BLASLONG, float *, BLASLONG , float *, BLASLONG , float * , BLASLONG);
|
||||
int (*sgemm_direct_performant) (BLASLONG M, BLASLONG N, BLASLONG K);
|
||||
void (*sgemm_direct_alpha_beta) (BLASLONG, BLASLONG, BLASLONG, float, float *, BLASLONG, float *, BLASLONG, float, float * , BLASLONG);
|
||||
void (*ssymm_direct_alpha_betaLU) (BLASLONG, BLASLONG, float, float *, BLASLONG, float *, BLASLONG, float, float * , BLASLONG);
|
||||
void (*ssymm_direct_alpha_betaLL) (BLASLONG, BLASLONG, float, float *, BLASLONG, float *, BLASLONG, float, float * , BLASLONG);
|
||||
void (*strmm_direct_LNUN) (BLASLONG, BLASLONG, float, float *, BLASLONG, float *, BLASLONG);
|
||||
void (*strmm_direct_LNLN) (BLASLONG, BLASLONG, float, float *, BLASLONG, float *, BLASLONG);
|
||||
void (*strmm_direct_LTUN) (BLASLONG, BLASLONG, float, float *, BLASLONG, float *, BLASLONG);
|
||||
void (*strmm_direct_LTLN) (BLASLONG, BLASLONG, float, float *, BLASLONG, float *, BLASLONG);
|
||||
void (*ssyrk_direct_alpha_betaUN) (BLASLONG, BLASLONG, float, float *, BLASLONG, float, float *, BLASLONG);
|
||||
void (*ssyrk_direct_alpha_betaUT) (BLASLONG, BLASLONG, float, float *, BLASLONG, float, float *, BLASLONG);
|
||||
void (*ssyrk_direct_alpha_betaLN) (BLASLONG, BLASLONG, float, float *, BLASLONG, float, float *, BLASLONG);
|
||||
void (*ssyrk_direct_alpha_betaLT) (BLASLONG, BLASLONG, float, float *, BLASLONG, float, float *, BLASLONG);
|
||||
void (*ssyr2k_direct_alpha_betaUN) (BLASLONG, BLASLONG, float, float *, BLASLONG, float *, BLASLONG, float, float *, BLASLONG);
|
||||
void (*ssyr2k_direct_alpha_betaUT) (BLASLONG, BLASLONG, float, float *, BLASLONG, float *, BLASLONG, float, float *, BLASLONG);
|
||||
void (*ssyr2k_direct_alpha_betaLN) (BLASLONG, BLASLONG, float, float *, BLASLONG, float *, BLASLONG, float, float *, BLASLONG);
|
||||
void (*ssyr2k_direct_alpha_betaLT) (BLASLONG, BLASLONG, float, float *, BLASLONG, float *, BLASLONG, float, float *, BLASLONG);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+29
-1
@@ -50,6 +50,20 @@
|
||||
#define SGEMM_DIRECT_PERFORMANT sgemm_direct_performant
|
||||
#define SGEMM_DIRECT sgemm_direct
|
||||
#define SGEMM_DIRECT_ALPHA_BETA sgemm_direct_alpha_beta
|
||||
#define SSYMM_DIRECT_ALPHA_BETA_LU ssymm_direct_alpha_betaLU
|
||||
#define SSYMM_DIRECT_ALPHA_BETA_LL ssymm_direct_alpha_betaLL
|
||||
#define STRMM_DIRECT_LNUN strmm_direct_LNUN
|
||||
#define STRMM_DIRECT_LNLN strmm_direct_LNLN
|
||||
#define STRMM_DIRECT_LTUN strmm_direct_LTUN
|
||||
#define STRMM_DIRECT_LTLN strmm_direct_LTLN
|
||||
#define SSYRK_DIRECT_ALPHA_BETA_UN ssyrk_direct_alpha_betaUN
|
||||
#define SSYRK_DIRECT_ALPHA_BETA_UT ssyrk_direct_alpha_betaUT
|
||||
#define SSYRK_DIRECT_ALPHA_BETA_LN ssyrk_direct_alpha_betaLN
|
||||
#define SSYRK_DIRECT_ALPHA_BETA_LT ssyrk_direct_alpha_betaLT
|
||||
#define SSYR2K_DIRECT_ALPHA_BETA_UN ssyr2k_direct_alpha_betaUN
|
||||
#define SSYR2K_DIRECT_ALPHA_BETA_UT ssyr2k_direct_alpha_betaUT
|
||||
#define SSYR2K_DIRECT_ALPHA_BETA_LN ssyr2k_direct_alpha_betaLN
|
||||
#define SSYR2K_DIRECT_ALPHA_BETA_LT ssyr2k_direct_alpha_betaLT
|
||||
|
||||
#define SGEMM_ONCOPY sgemm_oncopy
|
||||
#define SGEMM_OTCOPY sgemm_otcopy
|
||||
@@ -217,9 +231,23 @@
|
||||
#define SGEMM_DIRECT_PERFORMANT gotoblas -> sgemm_direct_performant
|
||||
#define SGEMM_DIRECT gotoblas -> sgemm_direct
|
||||
#elif ARCH_ARM64
|
||||
#define SGEMM_DIRECT_PERFORMANT sgemm_direct_performant
|
||||
#define SGEMM_DIRECT_PERFORMANT gotoblas -> sgemm_direct_performant
|
||||
#define SGEMM_DIRECT gotoblas -> sgemm_direct
|
||||
#define SGEMM_DIRECT_ALPHA_BETA gotoblas -> sgemm_direct_alpha_beta
|
||||
#define SSYMM_DIRECT_ALPHA_BETA_LU gotoblas -> ssymm_direct_alpha_betaLU
|
||||
#define SSYMM_DIRECT_ALPHA_BETA_LL gotoblas -> ssymm_direct_alpha_betaLL
|
||||
#define STRMM_DIRECT_LNUN gotoblas -> strmm_direct_LNUN
|
||||
#define STRMM_DIRECT_LNLN gotoblas -> strmm_direct_LNLN
|
||||
#define STRMM_DIRECT_LTUN gotoblas -> strmm_direct_LTUN
|
||||
#define STRMM_DIRECT_LTLN gotoblas -> strmm_direct_LTLN
|
||||
#define SSYRK_DIRECT_ALPHA_BETA_UN gotoblas -> ssyrk_direct_alpha_betaUN
|
||||
#define SSYRK_DIRECT_ALPHA_BETA_UT gotoblas -> ssyrk_direct_alpha_betaUT
|
||||
#define SSYRK_DIRECT_ALPHA_BETA_LN gotoblas -> ssyrk_direct_alpha_betaLN
|
||||
#define SSYRK_DIRECT_ALPHA_BETA_LT gotoblas -> ssyrk_direct_alpha_betaLT
|
||||
#define SSYR2K_DIRECT_ALPHA_BETA_UN gotoblas -> ssyr2k_direct_alpha_betaUN
|
||||
#define SSYR2K_DIRECT_ALPHA_BETA_UT gotoblas -> ssyr2k_direct_alpha_betaUT
|
||||
#define SSYR2K_DIRECT_ALPHA_BETA_LN gotoblas -> ssyr2k_direct_alpha_betaLN
|
||||
#define SSYR2K_DIRECT_ALPHA_BETA_LT gotoblas -> ssyr2k_direct_alpha_betaLT
|
||||
#endif
|
||||
|
||||
#define SGEMM_ONCOPY gotoblas -> sgemm_oncopy
|
||||
|
||||
+35
@@ -1,3 +1,31 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2025, The OpenBLAS Project
|
||||
* All rights reserved.
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name of the OpenBLAS project nor the names of
|
||||
* its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBLAS PROJECT OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* *****************************************************************************/
|
||||
|
||||
#ifndef COMMON_SH_H
|
||||
#define COMMON_SH_H
|
||||
|
||||
@@ -17,6 +45,9 @@
|
||||
#define SHGEMM_BETA shgemm_beta
|
||||
#define SHGEMM_KERNEL shgemm_kernel
|
||||
|
||||
#define SHGEMV_N_K shgemv_n
|
||||
#define SHGEMV_T_K shgemv_t
|
||||
|
||||
|
||||
#else // #DYNAMIC_ARCH
|
||||
|
||||
@@ -32,6 +63,10 @@
|
||||
|
||||
#define SHGEMM_BETA gotoblas -> shgemm_beta
|
||||
#define SHGEMM_KERNEL gotoblas -> shgemm_kernel
|
||||
|
||||
#define SHGEMV_N_K gotoblas->shgemv_n
|
||||
#define SHGEMV_T_K gotoblas->shgemv_t
|
||||
|
||||
#endif // #DYNAMIC_ARCH
|
||||
|
||||
#define SHGEMM_NN shgemm_nn
|
||||
|
||||
+54
-5
@@ -82,6 +82,7 @@ size_t length64=sizeof(value64);
|
||||
#define CPU_AMPERE1 25
|
||||
// Apple
|
||||
#define CPU_VORTEX 13
|
||||
#define CPU_VORTEXM4 26
|
||||
// Fujitsu
|
||||
#define CPU_A64FX 15
|
||||
// Phytium
|
||||
@@ -113,7 +114,8 @@ static char *cpuname[] = {
|
||||
"FT2000",
|
||||
"CORTEXA76",
|
||||
"NEOVERSEV2",
|
||||
"AMPERE1"
|
||||
"AMPERE1",
|
||||
"VORTEXM4",
|
||||
};
|
||||
|
||||
static char *cpuname_lower[] = {
|
||||
@@ -143,13 +145,15 @@ static char *cpuname_lower[] = {
|
||||
"cortexa76",
|
||||
"neoversev2",
|
||||
"ampere1",
|
||||
"ampere1a"
|
||||
"vortexm4"
|
||||
};
|
||||
|
||||
static int cpulowperf=0;
|
||||
static int cpumidperf=0;
|
||||
static int cpuhiperf=0;
|
||||
|
||||
int aliased = 0;
|
||||
|
||||
int get_feature(char *search)
|
||||
{
|
||||
|
||||
@@ -346,7 +350,7 @@ int detect(void)
|
||||
else if (strstr(cpu_implementer, "0x46") && strstr(cpu_part, "0x001"))
|
||||
return CPU_A64FX;
|
||||
// Apple
|
||||
else if (strstr(cpu_implementer, "0x61") && strstr(cpu_part, "0x022"))
|
||||
else if (strstr(cpu_implementer, "0x61") /* && strstr(cpu_part, "0x022")*/)
|
||||
return CPU_VORTEX;
|
||||
// Phytium
|
||||
else if (strstr(cpu_implementer, "0x70") && (strstr(cpu_part, "0x660") || strstr(cpu_part, "0x661")
|
||||
@@ -400,7 +404,8 @@ int detect(void)
|
||||
if (value64 ==131287967|| value64 == 458787763 ) return CPU_VORTEX; //A12/M1
|
||||
if (value64 == 3660830781) return CPU_VORTEX; //A15/M2
|
||||
if (value64 == 2271604202) return CPU_VORTEX; //A16/M3
|
||||
if (value64 == 1867590060) return CPU_VORTEX; //M4
|
||||
if (value64 == 1867590060) return CPU_VORTEXM4; //M4
|
||||
if (value64 == 492472296) return CPU_VORTEXM4; //M5
|
||||
#else
|
||||
#ifdef OS_WINDOWS
|
||||
HKEY reghandle;
|
||||
@@ -418,7 +423,10 @@ int detect(void)
|
||||
if (errcode != ERROR_SUCCESS) wprintf(L"Error reading cpuname from registry:%x\n",errcode);
|
||||
//wprintf(stderr,L"%s\n",(PWSTR)valstring);
|
||||
RegCloseKey(reghandle);
|
||||
if (strstr(valstring, "Snapdragon(R) X Elite")) return CPU_NEOVERSEN1;
|
||||
if (strstr(valstring, "Snapdragon(R) X Elite")) {
|
||||
aliased = 1;
|
||||
return CPU_NEOVERSEN1;
|
||||
}
|
||||
if (strstr(valstring, "Ampere(R) Altra")) return CPU_NEOVERSEN1;
|
||||
if (strstr(valstring, "Snapdragon (TM) 8cx Gen 3")) return CPU_CORTEXX1;
|
||||
if (strstr(valstring, "Snapdragon Compute Platform")) return CPU_CORTEXX1;
|
||||
@@ -541,6 +549,7 @@ void get_cpuconfig(void)
|
||||
break;
|
||||
case CPU_NEOVERSEN1:
|
||||
printf("#define %s\n", cpuname[d]);
|
||||
if (aliased == 0) {
|
||||
printf("#define L1_CODE_SIZE 65536\n");
|
||||
printf("#define L1_CODE_LINESIZE 64\n");
|
||||
printf("#define L1_CODE_ASSOCIATIVE 4\n");
|
||||
@@ -552,6 +561,23 @@ void get_cpuconfig(void)
|
||||
printf("#define L2_ASSOCIATIVE 8\n");
|
||||
printf("#define DTB_DEFAULT_ENTRIES 48\n");
|
||||
printf("#define DTB_SIZE 4096\n");
|
||||
} else {
|
||||
printf("#define L1_CODE_SIZE 196608\n");
|
||||
printf("#define L1_CODE_LINESIZE 64\n");
|
||||
printf("#define L1_CODE_ASSOCIATIVE 6\n");
|
||||
printf("#define L1_DATA_SIZE 98304\n");
|
||||
printf("#define L1_DATA_LINESIZE 64\n");
|
||||
printf("#define L1_DATA_ASSOCIATIVE 6\n");
|
||||
printf("#define L2_SIZE 12582912\n");
|
||||
printf("#define L2_LINESIZE 32\n");
|
||||
printf("#define L2_ASSOCIATIVE 12\n");
|
||||
printf("#define ITB_SIZE 4096\n");
|
||||
printf("#define ITB_ASSOCIATIVE 8\n");
|
||||
printf("#define ITB_DEFAULT_ENTRIES 256\n");
|
||||
printf("#define DTB_DEFAULT_ENTRIES 224\n");
|
||||
printf("#define DTB_ASSOCIATIVE 7\n");
|
||||
printf("#define DTB_SIZE 4096\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case CPU_NEOVERSEV1:
|
||||
@@ -726,6 +752,29 @@ void get_cpuconfig(void)
|
||||
break;
|
||||
case CPU_VORTEX:
|
||||
printf("#define VORTEX \n");
|
||||
#ifdef __APPLE__
|
||||
length64 = sizeof(value64);
|
||||
sysctlbyname("hw.l1icachesize",&value64,&length64,NULL,0);
|
||||
printf("#define L1_CODE_SIZE %lld \n",value64);
|
||||
length64 = sizeof(value64);
|
||||
sysctlbyname("hw.cachelinesize",&value64,&length64,NULL,0);
|
||||
printf("#define L1_CODE_LINESIZE %lld \n",value64);
|
||||
printf("#define L1_DATA_LINESIZE %lld \n",value64);
|
||||
length64 = sizeof(value64);
|
||||
sysctlbyname("hw.l1dcachesize",&value64,&length64,NULL,0);
|
||||
printf("#define L1_DATA_SIZE %lld \n",value64);
|
||||
length64 = sizeof(value64);
|
||||
sysctlbyname("hw.l2cachesize",&value64,&length64,NULL,0);
|
||||
printf("#define L2_SIZE %lld \n",value64);
|
||||
#endif
|
||||
printf("#define DTB_DEFAULT_ENTRIES 64 \n");
|
||||
printf("#define DTB_SIZE 4096 \n");
|
||||
break;
|
||||
case CPU_VORTEXM4:
|
||||
printf("#define VORTEXM4 \n");
|
||||
#ifdef __clang__
|
||||
printf("#define HAVE_SME 1 \n");
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
length64 = sizeof(value64);
|
||||
sysctlbyname("hw.l1icachesize",&value64,&length64,NULL,0);
|
||||
|
||||
+15
-10
@@ -217,8 +217,11 @@ in this section, since the process for each is quite different.
|
||||
For Visual Studio, you can use CMake to generate Visual Studio solution files;
|
||||
note that you will need at least CMake 3.11 for linking to work correctly).
|
||||
|
||||
Note that you need a Fortran compiler if you plan to build and use the LAPACK
|
||||
functions included with OpenBLAS. The sections below describe using either
|
||||
Note that you need a Fortran compiler if you plan to build and use the latest version
|
||||
of the LAPACK functions included with OpenBLAS. (If you do not have a Fortran compiler
|
||||
installed, you can build an older version of the LAPACK sources that has been converted
|
||||
to C - but its performance will likely be slower and accuracy may be poorer too.)
|
||||
The sections below describe using either
|
||||
`flang` as an add-on to clang/LLVM or `gfortran` as part of MinGW for this
|
||||
purpose. If you want to use the Intel Fortran compiler (`ifort` or `ifx`) for
|
||||
this, be sure to also use the Intel C compiler (`icc` or `icx`) for building
|
||||
@@ -226,21 +229,22 @@ the C parts, as the ABI imposed by `ifort` is incompatible with MSVC
|
||||
|
||||
A fully-optimized OpenBLAS that can be statically or dynamically linked to your
|
||||
application can currently be built for the 64-bit architecture with the LLVM
|
||||
compiler infrastructure. We're going to use [Miniconda3](https://docs.anaconda.com/miniconda/)
|
||||
compiler infrastructure. We're going to use [Miniforge3] the pre-configured
|
||||
and more versatile alternative to [Miniconda](https://docs.anaconda.com/miniconda/)
|
||||
to grab all of the tools we need, since some of them are in an experimental
|
||||
status. Before you begin, you'll need to have Microsoft Visual Studio 2015 or
|
||||
newer installed.
|
||||
|
||||
1. Install Miniconda3 for 64-bit Windows using `winget install --id Anaconda.Miniconda3`,
|
||||
or easily download from [conda.io](https://docs.conda.io/en/latest/miniconda.html).
|
||||
2. Open the "Anaconda Command Prompt" now available in the Start Menu, or at `%USERPROFILE%\miniconda3\shell\condabin\conda-hook.ps1`.
|
||||
1. Install Miniforge for 64-bit Windows with the latest version of the installer Miniforge3-Windows-x86_64.exe
|
||||
available on [github.com](https://github.com/conda-forge/miniforge/releases/)
|
||||
2. Open the "Miniforge Command Prompt" now available in the Start Menu, or at `%USERPROFILE%\miniforge3\shell\condabin\conda-hook.ps1`.
|
||||
3. In that command prompt window, use `cd` to change to the directory where you want to build OpenBLAS.
|
||||
4. Now install all of the tools we need:
|
||||
```
|
||||
conda update -n base conda
|
||||
conda config --add channels conda-forge
|
||||
conda install -y cmake flang clangdev perl libflang ninja
|
||||
conda install -y cmake flang_win-64 clangdev perl libflang ninja
|
||||
```
|
||||
(if you want to build with OpenMP support, add `llvm-openmp` and `llvm-openmp-fortran`)
|
||||
5. Still in the Anaconda Command Prompt window, activate the 64-bit MSVC environment with `vcvarsall x64`.
|
||||
On Windows 11 with Visual Studio 2022, this would be done by invoking:
|
||||
|
||||
@@ -708,9 +712,10 @@ fully working OpenBLAS for this platform.
|
||||
|
||||
Go to the directory where you unpacked OpenBLAS,and enter the following commands:
|
||||
```bash
|
||||
CC=/Applications/Xcode_12.4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
|
||||
CC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang"
|
||||
|
||||
CFLAGS= -O2 -Wno-macro-redefined -isysroot /Applications/Xcode_12.4.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.4.sdk -arch arm64 -miphoneos-version-min=10.0
|
||||
SDKROOT="$(xcrun --sdk iphoneos --show-sdk-path)"
|
||||
CFLAGS="-O2 -Wno-macro-redefined -isysroot $SDKROOT -arch arm64 -miphoneos-version-min=10.0"
|
||||
|
||||
make TARGET=ARMV8 DYNAMIC_ARCH=1 NUM_THREADS=32 HOSTCC=clang NOFORTRAN=1
|
||||
```
|
||||
|
||||
@@ -202,6 +202,15 @@ if (BUILD_BFLOAT16)
|
||||
if (USE_THREAD)
|
||||
GenerateNamedObjects("sbgemv_thread.c" "" "gemv_thread_n" false "" "" false "BFLOAT16")
|
||||
GenerateNamedObjects("sbgemv_thread.c" "TRANSA" "gemv_thread_t" false "" "" false "BFLOAT16")
|
||||
GenerateNamedObjects("sbgemv_thread.c" "BGEMM;BFLOAT16" "bgemv_thread_n" false "" "" true "")
|
||||
GenerateNamedObjects("sbgemv_thread.c" "BGEMM;BFLOAT16;TRANSA" "bgemv_thread_t" false "" "" true "")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (BUILD_HFLOAT16)
|
||||
if (USE_THREAD)
|
||||
GenerateNamedObjects("sbgemv_thread.c" "" "gemv_thread_n" false "" "" false "HFLOAT16")
|
||||
GenerateNamedObjects("sbgemv_thread.c" "TRANSA" "gemv_thread_t" false "" "" false "HFLOAT16")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
||||
@@ -450,6 +450,12 @@ XBLASOBJS += \
|
||||
xtbmv_thread_CUU.$(SUFFIX) xtbmv_thread_CUN.$(SUFFIX) \
|
||||
xtbmv_thread_CLU.$(SUFFIX) xtbmv_thread_CLN.$(SUFFIX)
|
||||
|
||||
|
||||
ifeq ($(BUILD_HFLOAT16),1)
|
||||
SHBLASOBJS += \
|
||||
shgemv_thread_n$(TSUFFIX).$(SUFFIX) \
|
||||
shgemv_thread_t$(TSUFFIX).$(SUFFIX)
|
||||
endif
|
||||
ifeq ($(BUILD_BFLOAT16),1)
|
||||
BBLASOBJS += \
|
||||
bgemv_thread_n$(TSUFFIX).$(SUFFIX) \
|
||||
@@ -3737,6 +3743,13 @@ xtrsv_CUU.$(SUFFIX) xtrsv_CUU.$(PSUFFIX) : ztrsv_L.c ../../param.h
|
||||
xtrsv_CUN.$(SUFFIX) xtrsv_CUN.$(PSUFFIX) : ztrsv_L.c ../../param.h
|
||||
$(CC) -c $(CFLAGS) -DXDOUBLE -DCOMPLEX -DTRANSA=4 -UUNIT $< -o $(@F)
|
||||
|
||||
ifeq ($(BUILD_HFLOAT16),1)
|
||||
shgemv_thread_n.$(SUFFIX) shgemv_thread_n.$(PSUFFIX) : sbgemv_thread.c ../../common.h
|
||||
$(CC) -c $(CFLAGS) -UCOMPLEX -UDOUBLE -UTRANSA -UCONJ -UXCONJ $< -o $(@F)
|
||||
shgemv_thread_t.$(SUFFIX) shgemv_thread_t.$(PSUFFIX) : sbgemv_thread.c ../../common.h
|
||||
$(CC) -c $(CFLAGS) -UCOMPLEX -UDOUBLE -DTRANSA -UCONJ -UXCONJ $< -o $(@F)
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_BFLOAT16),1)
|
||||
bgemv_thread_n.$(SUFFIX) bgemv_thread_n.$(PSUFFIX) : sbgemv_thread.c ../../common.h
|
||||
$(CC) -c $(CFLAGS) -DBGEMM -UCOMPLEX -UDOUBLE -UTRANSA -UCONJ -UXCONJ $< -o $(@F)
|
||||
|
||||
@@ -17,6 +17,7 @@ foreach (GEMM_DEFINE ${GEMM_DEFINES})
|
||||
GenerateNamedObjects("gemm.c" "${GEMM_DEFINE};BGEMM" "gemm_${GEMM_DEFINE_LC}" 0 "" "" false "BFLOAT16")
|
||||
if (USE_THREAD AND NOT USE_SIMPLE_THREADED_LEVEL3)
|
||||
GenerateNamedObjects("gemm.c" "${GEMM_DEFINE};THREADED_LEVEL3" "gemm_thread_${GEMM_DEFINE_LC}" 0 "" "" false "BFLOAT16")
|
||||
GenerateNamedObjects("gemm.c" "${GEMM_DEFINE};THREADED_LEVEL3;BGEMM" "gemm_thread_${GEMM_DEFINE_LC}" 0 "" "" false "BFLOAT16")
|
||||
endif ()
|
||||
endif ()
|
||||
if (BUILD_HFLOAT16)
|
||||
|
||||
@@ -588,8 +588,6 @@ static int gemm_driver(blas_arg_t *args, BLASLONG *range_m, BLASLONG
|
||||
InitializeCriticalSection((PCRITICAL_SECTION)&level3_lock);
|
||||
#else
|
||||
static pthread_mutex_t level3_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t level3_wakeup = PTHREAD_COND_INITIALIZER;
|
||||
volatile static BLASLONG CPU_AVAILABLE = MAX_CPU_NUMBER;
|
||||
#endif
|
||||
|
||||
blas_arg_t newarg;
|
||||
@@ -659,12 +657,6 @@ static int gemm_driver(blas_arg_t *args, BLASLONG *range_m, BLASLONG
|
||||
EnterCriticalSection((PCRITICAL_SECTION)&level3_lock);
|
||||
#else
|
||||
pthread_mutex_lock(&level3_lock);
|
||||
while(CPU_AVAILABLE < nthreads) {
|
||||
pthread_cond_wait(&level3_wakeup, &level3_lock);
|
||||
}
|
||||
CPU_AVAILABLE -= nthreads;
|
||||
WMB;
|
||||
pthread_mutex_unlock(&level3_lock);
|
||||
#endif
|
||||
|
||||
#ifdef USE_ALLOC_HEAP
|
||||
@@ -816,10 +808,6 @@ static int gemm_driver(blas_arg_t *args, BLASLONG *range_m, BLASLONG
|
||||
#elif defined(OS_WINDOWS)
|
||||
LeaveCriticalSection((PCRITICAL_SECTION)&level3_lock);
|
||||
#else
|
||||
pthread_mutex_lock(&level3_lock);
|
||||
CPU_AVAILABLE += nthreads;
|
||||
WMB;
|
||||
pthread_cond_signal(&level3_wakeup);
|
||||
pthread_mutex_unlock(&level3_lock);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ if (USE_THREAD)
|
||||
set(BLAS_SERVER blas_server_omp.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
|
||||
set(BLAS_SERVER blas_server_win32.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL CYGWIN)
|
||||
set(BLAS_SERVER blas_server_win32.c)
|
||||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "WindowsStore")
|
||||
set(BLAS_SERVER blas_server_win32.c)
|
||||
endif ()
|
||||
|
||||
@@ -637,9 +637,7 @@ int exec_blas_async(BLASLONG pos, blas_queue_t *queue){
|
||||
|
||||
#ifdef SMP_SERVER
|
||||
// Handle lazy re-init of the thread-pool after a POSIX fork
|
||||
LOCK_COMMAND(&server_lock);
|
||||
if (unlikely(blas_server_avail == 0)) blas_thread_init();
|
||||
UNLOCK_COMMAND(&server_lock);
|
||||
#endif
|
||||
BLASLONG i = 0;
|
||||
blas_queue_t *current = queue;
|
||||
|
||||
@@ -128,6 +128,12 @@ extern gotoblas_t gotoblas_ARMV9SME;
|
||||
#else
|
||||
#define gotoblas_ARMV9SME gotoblas_ARMV8
|
||||
#endif
|
||||
#ifdef DYN_VORTEXM4
|
||||
extern gotoblas_t gotoblas_VORTEXM4;
|
||||
#else
|
||||
#error "dont have vortexm4"
|
||||
#define gotoblas_VORTEXM4 gotoblas_ARMV8
|
||||
#endif
|
||||
#ifdef DYN_CORTEXA55
|
||||
extern gotoblas_t gotoblas_CORTEXA55;
|
||||
#else
|
||||
@@ -155,17 +161,26 @@ extern gotoblas_t gotoblas_NEOVERSEV1;
|
||||
extern gotoblas_t gotoblas_NEOVERSEN2;
|
||||
extern gotoblas_t gotoblas_ARMV8SVE;
|
||||
extern gotoblas_t gotoblas_A64FX;
|
||||
#ifndef NO_SME
|
||||
extern gotoblas_t gotoblas_ARMV9SME;
|
||||
#else
|
||||
#define gotoblas_ARMV9SME gotoblas_ARMV8SVE
|
||||
#endif
|
||||
#else
|
||||
#define gotoblas_NEOVERSEV1 gotoblas_ARMV8
|
||||
#define gotoblas_NEOVERSEN2 gotoblas_ARMV8
|
||||
#define gotoblas_ARMV8SVE gotoblas_ARMV8
|
||||
#define gotoblas_A64FX gotoblas_ARMV8
|
||||
#define gotoblas_ARMV9SME gotoblas_ARMV8
|
||||
#endif
|
||||
#ifndef NO_SME
|
||||
extern gotoblas_t gotoblas_ARMV9SME;
|
||||
#if defined (__clang__) && defined(OS_DARWIN)
|
||||
extern gotoblas_t gotoblas_VORTEXM4;
|
||||
#else
|
||||
#define gotoblas_VORTEXM4 gotoblas_NEOVERSEN1
|
||||
#endif
|
||||
#else
|
||||
#ifndef NO_SVE
|
||||
#define gotoblas_ARMV9SME gotoblas_ARMV8SVE
|
||||
#else
|
||||
#define gotoblas_ARMV9SME gotoblas_NEOVERSEN1
|
||||
#endif
|
||||
#define gotoblas_VORTEXM4 gotoblas_NEOVERSEN1
|
||||
#endif
|
||||
|
||||
extern gotoblas_t gotoblas_THUNDERX3T110;
|
||||
@@ -176,7 +191,7 @@ extern void openblas_warning(int verbose, const char * msg);
|
||||
#define FALLBACK_VERBOSE 1
|
||||
#define NEOVERSEN1_FALLBACK "OpenBLAS : Your OS does not support SVE instructions. OpenBLAS is using Neoverse N1 kernels as a fallback, which may give poorer performance.\n"
|
||||
|
||||
#define NUM_CORETYPES 19
|
||||
#define NUM_CORETYPES 20
|
||||
|
||||
/*
|
||||
* In case asm/hwcap.h is outdated on the build system, make sure
|
||||
@@ -216,6 +231,7 @@ static char *corename[] = {
|
||||
"armv8sve",
|
||||
"a64fx",
|
||||
"armv9sme",
|
||||
"vortexm4",
|
||||
"unknown"
|
||||
};
|
||||
|
||||
@@ -239,6 +255,7 @@ char *gotoblas_corename(void) {
|
||||
if (gotoblas == &gotoblas_ARMV8SVE) return corename[16];
|
||||
if (gotoblas == &gotoblas_A64FX) return corename[17];
|
||||
if (gotoblas == &gotoblas_ARMV9SME) return corename[18];
|
||||
if (gotoblas == &gotoblas_VORTEXM4) return corename[19];
|
||||
return corename[NUM_CORETYPES];
|
||||
}
|
||||
|
||||
@@ -277,6 +294,7 @@ static gotoblas_t *force_coretype(char *coretype) {
|
||||
case 16: return (&gotoblas_ARMV8SVE);
|
||||
case 17: return (&gotoblas_A64FX);
|
||||
case 18: return (&gotoblas_ARMV9SME);
|
||||
case 19: return (&gotoblas_VORTEXM4);
|
||||
}
|
||||
snprintf(message, 128, "Core not found: %s\n", coretype);
|
||||
openblas_warning(1, message);
|
||||
@@ -288,11 +306,11 @@ static gotoblas_t *get_coretype(void) {
|
||||
char coremsg[128];
|
||||
|
||||
#if defined (OS_DARWIN)
|
||||
//future #if !defined(NO_SME)
|
||||
// if (support_sme1()) {
|
||||
// return &gotoblas_ARMV9SME;
|
||||
// }
|
||||
// #endif
|
||||
#if !defined(NO_SME)
|
||||
if (support_sme1()) {
|
||||
return &gotoblas_VORTEXM4;
|
||||
}
|
||||
#endif
|
||||
return &gotoblas_NEOVERSEN1;
|
||||
#endif
|
||||
|
||||
@@ -463,7 +481,7 @@ static gotoblas_t *get_coretype(void) {
|
||||
}
|
||||
break;
|
||||
case 0x61: // Apple
|
||||
//future if (support_sme1()) return &gotoblas_ARMV9SME;
|
||||
if (support_sme1()) return &gotoblas_VORTEXM4;
|
||||
return &gotoblas_NEOVERSEN1;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -99,6 +99,7 @@ struct riscv_hwprobe {
|
||||
#define RISCV_HWPROBE_IMA_V (1 << 2)
|
||||
#define RISCV_HWPROBE_EXT_ZFH (1 << 27)
|
||||
#define RISCV_HWPROBE_EXT_ZVFH (1 << 30)
|
||||
#define RISCV_HWPROBE_EXT_ZVFBFWMA (1 << 54)
|
||||
|
||||
#ifndef NR_riscv_hwprobe
|
||||
#ifndef NR_arch_specific_syscall
|
||||
@@ -170,6 +171,8 @@ static gotoblas_t* get_coretype(void) {
|
||||
if (ret == 0) {
|
||||
#if defined(BUILD_HFLOAT16)
|
||||
vector_mask = (RISCV_HWPROBE_IMA_V | RISCV_HWPROBE_EXT_ZFH | RISCV_HWPROBE_EXT_ZVFH);
|
||||
#elif defined(BUILD_BFLOAT16)
|
||||
vector_mask = (RISCV_HWPROBE_IMA_V | RISCV_HWPROBE_EXT_ZVFBFWMA);
|
||||
#else
|
||||
vector_mask = RISCV_HWPROBE_IMA_V;
|
||||
#endif
|
||||
@@ -180,6 +183,10 @@ static gotoblas_t* get_coretype(void) {
|
||||
snprintf(coremsg, sizeof(coremsg), "Cpu support for Zfh+Zvfh extensions required due to BUILD_HFLOAT16=1\n");
|
||||
openblas_warning(1, coremsg);
|
||||
return NULL;
|
||||
#elif defined(BUILD_BFLOAT16)
|
||||
snprintf(coremsg, sizeof(coremsg), "Cpu support for Zvfbfwma extensions required due to BUILD_BFLOAT16=1\n");
|
||||
openblas_warning(1, coremsg);
|
||||
return NULL;
|
||||
#else
|
||||
if (!(getauxval(AT_HWCAP) & DETECT_RISCV64_HWCAP_ISA_V))
|
||||
return NULL;
|
||||
|
||||
+2
-1
@@ -80,7 +80,7 @@ blasobjsz="
|
||||
|
||||
blasobjs="lsame xerbla"
|
||||
bfblasobjs="bgemm bgemv sbgemm sbgemmt sbgemmtr sbgemv sbdot sbstobf16 sbdtobf16 sbf16tos dbf16tod"
|
||||
hfblasobjs="shgemm"
|
||||
hfblasobjs="shgemm shgemv"
|
||||
cblasobjsc="
|
||||
cblas_caxpy cblas_ccopy cblas_cdotc cblas_cdotu cblas_cgbmv cblas_cgemm cblas_cgemv
|
||||
cblas_cgerc cblas_cgeru cblas_chbmv cblas_chemm cblas_chemv cblas_cher2 cblas_cher2k
|
||||
@@ -181,6 +181,7 @@ misc_no_underscore_objs="
|
||||
goto_set_num_threads
|
||||
openblas_get_config
|
||||
openblas_get_corename
|
||||
openblas_set_threads_callback_function
|
||||
"
|
||||
|
||||
misc_underscore_objs=""
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
@blasobjs = (lsame, xerbla);
|
||||
@bfblasobjs = (bgemm, bgemv, sbgemm, sbgemmt, sbgemmtr, sbgemv, sbdot, sbstobf16, sbdtobf16, sbf16tos, dbf16tod);
|
||||
@hfblasobjs = (shgemm);
|
||||
@hfblasobjs = (shgemm, shgemv);
|
||||
@cblasobjsc = (
|
||||
cblas_caxpy, cblas_ccopy, cblas_cdotc, cblas_cdotu, cblas_cgbmv, cblas_cgemm, cblas_cgemv,
|
||||
cblas_cgerc, cblas_cgeru, cblas_chbmv, cblas_chemm, cblas_chemv, cblas_cher2, cblas_cher2k,
|
||||
@@ -177,6 +177,7 @@
|
||||
goto_set_num_threads,
|
||||
openblas_get_config,
|
||||
openblas_get_corename,
|
||||
openblas_set_threads_callback_function,
|
||||
);
|
||||
|
||||
@misc_underscore_objs = (
|
||||
|
||||
@@ -30,9 +30,11 @@ nofortran=0
|
||||
shift 2
|
||||
compiler="$*"
|
||||
compiler_bin="$1"
|
||||
shift
|
||||
compiler_args="$*"
|
||||
|
||||
# f77 is too ambiguous
|
||||
[ "$compiler" = "f77" ] && compiler=''
|
||||
[ "$compiler_bin" = "f77" ] && compiler=''
|
||||
|
||||
path=`split "$PATH" ':'`
|
||||
|
||||
@@ -50,7 +52,7 @@ if [ -z "$compiler" ]; then
|
||||
for list in $lists; do
|
||||
for p in $path; do
|
||||
if [ -x "$p/$list" ]; then
|
||||
compiler=$list
|
||||
compiler="$list $compiler_args"
|
||||
compiler_bin=$list
|
||||
break 2
|
||||
fi
|
||||
@@ -90,7 +92,7 @@ else
|
||||
vendor=FLANG
|
||||
openmp='-fopenmp'
|
||||
;;
|
||||
*GNU*|*GCC*)
|
||||
*GCC*)
|
||||
|
||||
v="${data#*GCC: *\) }"
|
||||
v="${v%%\"*}"
|
||||
|
||||
@@ -1654,6 +1654,28 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#define CORENAME "VORTEX"
|
||||
#endif
|
||||
|
||||
#ifdef FORCE_VORTEXM4
|
||||
#define FORCE
|
||||
#define ARCHITECTURE "ARM64"
|
||||
#define SUBARCHITECTURE "VORTEXM4"
|
||||
#define SUBDIRNAME "arm64"
|
||||
#ifdef __clang__
|
||||
#define ARCHCONFIG "-DVORTEXM4 " \
|
||||
"-DL1_DATA_SIZE=32768 -DL1_DATA_LINESIZE=64 " \
|
||||
"-DL2_SIZE=262144 -DL2_LINESIZE=64 " \
|
||||
"-DDTB_DEFAULT_ENTRIES=64 -DDTB_SIZE=4096 -DL2_ASSOCIATIVE=32 " \
|
||||
"-DHAVE_VFPV4 -DHAVE_VFPV3 -DHAVE_VFP -DHAVE_NEON -DHAVE_SME -DARMV8"
|
||||
#else
|
||||
#define ARCHCONFIG "-DVORTEX " \
|
||||
"-DL1_DATA_SIZE=32768 -DL1_DATA_LINESIZE=64 " \
|
||||
"-DL2_SIZE=262144 -DL2_LINESIZE=64 " \
|
||||
"-DDTB_DEFAULT_ENTRIES=64 -DDTB_SIZE=4096 -DL2_ASSOCIATIVE=32 " \
|
||||
"-DHAVE_VFPV4 -DHAVE_VFPV3 -DHAVE_VFP -DHAVE_NEON -DARMV8"
|
||||
#endif
|
||||
#define LIBNAME "vortexm4"
|
||||
#define CORENAME "VORTEXM4"
|
||||
#endif
|
||||
|
||||
#ifdef FORCE_A64FX
|
||||
#define ARMV8
|
||||
#define FORCE
|
||||
@@ -2046,10 +2068,9 @@ int main(int argc, char *argv[]){
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef INTEL_AMD
|
||||
#ifndef FORCE
|
||||
#if defined(INTEL_AMD) && !defined(FORCE)
|
||||
get_sse();
|
||||
#else
|
||||
#elif defined(FORCE_INTEL)
|
||||
|
||||
sprintf(buffer, "%s", ARCHCONFIG);
|
||||
|
||||
@@ -2079,7 +2100,6 @@ int main(int argc, char *argv[]){
|
||||
} else p ++;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
printf("__BYTE_ORDER__=__ORDER_BIG_ENDIAN__\n");
|
||||
|
||||
@@ -125,6 +125,7 @@ foreach (CBLAS_FLAG ${CBLAS_FLAGS})
|
||||
if (BUILD_SINGLE OR BUILD_DOUBLE)
|
||||
GenerateNamedObjects("sdsdot.c" "" "sdsdot" ${CBLAS_FLAG} "" "" true "SINGLE")
|
||||
GenerateNamedObjects("gemm_batch.c" "" "gemm_batch" ${CBLAS_FLAG} "" "" false)
|
||||
GenerateNamedObjects("gemm_batch_strided.c" "" "gemm_batch_strided" ${CBLAS_FLAG} "" "" false)
|
||||
endif ()
|
||||
if (BUILD_DOUBLE)
|
||||
GenerateNamedObjects("dsdot.c" "" "dsdot" ${CBLAS_FLAG} "" "" true "SINGLE")
|
||||
@@ -161,9 +162,11 @@ if (BUILD_BFLOAT16)
|
||||
GenerateNamedObjects("bf16to.c" "SINGLE_PREC" "sbf16tos" ${CBLAS_FLAG} "" "" true "BFLOAT16")
|
||||
GenerateNamedObjects("bf16to.c" "DOUBLE_PREC" "dbf16tod" ${CBLAS_FLAG} "" "" true "BFLOAT16")
|
||||
GenerateNamedObjects("gemm_batch.c" "" "sbgemm_batch" ${CBLAS_FLAG} "" "" true "BFLOAT16")
|
||||
GenerateNamedObjects("gemm_batch_strided.c" "" "sbgemm_batch_strided" ${CBLAS_FLAG} "" "" true "BFLOAT16")
|
||||
endif ()
|
||||
if (BUILD_HFLOAT16)
|
||||
GenerateNamedObjects("gemm.c" "" "shgemm" ${CBLAS_FLAG} "" "" true "HFLOAT16")
|
||||
GenerateNamedObjects("sbgemv.c" "" "shgemv" ${CBLAS_FLAG} "" "" true "HFLOAT16")
|
||||
endif ()
|
||||
|
||||
# complex-specific sources
|
||||
@@ -194,6 +197,7 @@ foreach (float_type ${FLOAT_TYPES})
|
||||
GenerateNamedObjects("asum.c" "" "scasum" ${CBLAS_FLAG} "" "" true "COMPLEX")
|
||||
GenerateNamedObjects("sum.c" "" "scsum" ${CBLAS_FLAG} "" "" true "COMPLEX")
|
||||
GenerateNamedObjects("gemm_batch.c" "" "cgemm_batch" ${CBLAS_FLAG} "" "" true "COMPLEX")
|
||||
GenerateNamedObjects("gemm_batch_strided.c" "" "cgemm_batch_strided" ${CBLAS_FLAG} "" "" true "COMPLEX")
|
||||
endif ()
|
||||
if (${float_type} STREQUAL "ZCOMPLEX")
|
||||
GenerateNamedObjects("zscal.c" "SSCAL" "dscal" ${CBLAS_FLAG} "" "" false "ZCOMPLEX")
|
||||
@@ -204,6 +208,7 @@ foreach (float_type ${FLOAT_TYPES})
|
||||
GenerateNamedObjects("asum.c" "" "dzasum" ${CBLAS_FLAG} "" "" true "ZCOMPLEX")
|
||||
GenerateNamedObjects("sum.c" "" "dzsum" ${CBLAS_FLAG} "" "" true "ZCOMPLEX")
|
||||
GenerateNamedObjects("gemm_batch.c" "" "zgemm_batch" ${CBLAS_FLAG} "" "" true "ZCOMPLEX")
|
||||
GenerateNamedObjects("gemm_batch_strided.c" "" "zgemm_batch_strided" ${CBLAS_FLAG} "" "" true "ZCOMPLEX")
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
@@ -255,6 +260,7 @@ if ( BUILD_COMPLEX AND NOT BUILD_SINGLE)
|
||||
GenerateNamedObjects("gemv.c" "" "gemv" 0 "" "" false "SINGLE")
|
||||
GenerateNamedObjects("gemm.c" "" "gemm" 0 "" "" false "SINGLE")
|
||||
GenerateNamedObjects("gemm_batch.c" "" "gemm_batch" 0 "" "" false "SINGLE")
|
||||
GenerateNamedObjects("gemm_batch_strided.c" "" "gemm_batch_strided" 0 "" "" false "SINGLE")
|
||||
GenerateNamedObjects("asum.c" "" "asum" 0 "" "" false "SINGLE")
|
||||
GenerateNamedObjects("swap.c" "" "swap" 0 "" "" false "SINGLE")
|
||||
GenerateNamedObjects("axpy.c" "" "axpy" 0 "" "" false "SINGLE")
|
||||
@@ -269,6 +275,7 @@ if ( BUILD_COMPLEX16 AND NOT BUILD_DOUBLE)
|
||||
GenerateNamedObjects("gemv.c" "" "gemv" 0 "" "" false "DOUBLE")
|
||||
GenerateNamedObjects("gemm.c" "" "gemm" 0 "" "" false "DOUBLE")
|
||||
GenerateNamedObjects("gemm_batch.c" "" "gemm_batch" 0 "" "" false "DOUBLE")
|
||||
GenerateNamedObjects("gemm_batch_strided.c" "" "gemm_batch_strided" 0 "" "" false "DOUBLE")
|
||||
GenerateNamedObjects("asum.c" "" "asum" 0 "" "" false "DOUBLE")
|
||||
GenerateNamedObjects("swap.c" "" "swap" 0 "" "" false "DOUBLE")
|
||||
GenerateNamedObjects("axpy.c" "" "axpy" 0 "" "" false "DOUBLE")
|
||||
|
||||
+54
-12
@@ -73,7 +73,7 @@ SBLAS3OBJS = \
|
||||
strsm.$(SUFFIX) ssyrk.$(SUFFIX) ssyr2k.$(SUFFIX) \
|
||||
somatcopy.$(SUFFIX) simatcopy.$(SUFFIX)\
|
||||
sgeadd.$(SUFFIX) sgemmt.$(SUFFIX) sgemmtr.$(SUFFIX) \
|
||||
sgemm_batch.$(SUFFIX)
|
||||
sgemm_batch.$(SUFFIX) sgemm_batch_strided.$(SUFFIX)
|
||||
|
||||
ifeq ($(BUILD_BFLOAT16),1)
|
||||
BBLAS3OBJS = bgemm.$(SUFFIX)
|
||||
@@ -81,12 +81,13 @@ BBLAS2OBJS = bgemv.$(SUFFIX)
|
||||
BBLAS1OBJS = bscal.$(SUFFIX)
|
||||
SBBLAS1OBJS = sbdot.$(SUFFIX)
|
||||
SBBLAS2OBJS = sbgemv.$(SUFFIX)
|
||||
SBBLAS3OBJS = sbgemm.$(SUFFIX) sbgemmt.$(SUFFIX) sbgemmtr.$(SUFFIX) sbgemm_batch.$(SUFFIX)
|
||||
SBBLAS3OBJS = sbgemm.$(SUFFIX) sbgemmt.$(SUFFIX) sbgemmtr.$(SUFFIX) sbgemm_batch.$(SUFFIX) sbgemm_batch_strided.$(SUFFIX)
|
||||
SBEXTOBJS = sbstobf16.$(SUFFIX) sbdtobf16.$(SUFFIX) sbf16tos.$(SUFFIX) dbf16tod.$(SUFFIX)
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_HFLOAT16),1)
|
||||
SHBLAS3OBJS = shgemm.$(SUFFIX)
|
||||
SHBLAS2OBJS = shgemv.$(SUFFIX)
|
||||
endif
|
||||
|
||||
DBLAS1OBJS = \
|
||||
@@ -113,7 +114,7 @@ DBLAS3OBJS = \
|
||||
dtrsm.$(SUFFIX) dsyrk.$(SUFFIX) dsyr2k.$(SUFFIX) \
|
||||
domatcopy.$(SUFFIX) dimatcopy.$(SUFFIX)\
|
||||
dgeadd.$(SUFFIX) dgemmt.$(SUFFIX) dgemmtr.$(SUFFIX) \
|
||||
dgemm_batch.$(SUFFIX)
|
||||
dgemm_batch.$(SUFFIX) dgemm_batch_strided.$(SUFFIX)
|
||||
|
||||
CBLAS1OBJS = \
|
||||
caxpy.$(SUFFIX) caxpyc.$(SUFFIX) cswap.$(SUFFIX) \
|
||||
@@ -143,7 +144,7 @@ CBLAS3OBJS = \
|
||||
chemm.$(SUFFIX) cherk.$(SUFFIX) cher2k.$(SUFFIX) \
|
||||
comatcopy.$(SUFFIX) cimatcopy.$(SUFFIX)\
|
||||
cgeadd.$(SUFFIX) cgemmt.$(SUFFIX) cgemmtr.$(SUFFIX) \
|
||||
cgemm_batch.$(SUFFIX)
|
||||
cgemm_batch.$(SUFFIX) cgemm_batch_strided.$(SUFFIX)
|
||||
|
||||
ZBLAS1OBJS = \
|
||||
zaxpy.$(SUFFIX) zaxpyc.$(SUFFIX) zswap.$(SUFFIX) \
|
||||
@@ -173,7 +174,7 @@ ZBLAS3OBJS = \
|
||||
zhemm.$(SUFFIX) zherk.$(SUFFIX) zher2k.$(SUFFIX) \
|
||||
zomatcopy.$(SUFFIX) zimatcopy.$(SUFFIX)\
|
||||
zgeadd.$(SUFFIX) zgemmt.$(SUFFIX) zgemmtr.$(SUFFIX) \
|
||||
zgemm_batch.$(SUFFIX)
|
||||
zgemm_batch.$(SUFFIX) zgemm_batch_strided.$(SUFFIX)
|
||||
|
||||
ifeq ($(SUPPORT_GEMM3M), 1)
|
||||
|
||||
@@ -321,7 +322,7 @@ CSBLAS2OBJS = \
|
||||
CSBLAS3OBJS = \
|
||||
cblas_sgemm.$(SUFFIX) cblas_ssymm.$(SUFFIX) cblas_strmm.$(SUFFIX) cblas_strsm.$(SUFFIX) \
|
||||
cblas_ssyrk.$(SUFFIX) cblas_ssyr2k.$(SUFFIX) cblas_somatcopy.$(SUFFIX) cblas_simatcopy.$(SUFFIX)\
|
||||
cblas_sgeadd.$(SUFFIX) cblas_sgemmt.$(SUFFIX) cblas_sgemmtr.$(SUFFIX) cblas_sgemm_batch.$(SUFFIX)
|
||||
cblas_sgeadd.$(SUFFIX) cblas_sgemmt.$(SUFFIX) cblas_sgemmtr.$(SUFFIX) cblas_sgemm_batch.$(SUFFIX) cblas_sgemm_batch_strided.$(SUFFIX)
|
||||
|
||||
ifeq ($(BUILD_BFLOAT16),1)
|
||||
CBBLAS3OBJS = cblas_bgemm.$(SUFFIX)
|
||||
@@ -329,7 +330,7 @@ CBBLAS2OBJS = cblas_bgemv.$(SUFFIX)
|
||||
CBBLAS1OBJS = cblas_bscal.$(SUFFIX)
|
||||
CSBBLAS1OBJS = cblas_sbdot.$(SUFFIX)
|
||||
CSBBLAS2OBJS = cblas_sbgemv.$(SUFFIX)
|
||||
CSBBLAS3OBJS = cblas_sbgemm.$(SUFFIX) cblas_sbgemmt.$(SUFFIX) cblas_sbgemmtr.$(SUFFIX) cblas_sbgemm_batch.$(SUFFIX)
|
||||
CSBBLAS3OBJS = cblas_sbgemm.$(SUFFIX) cblas_sbgemmt.$(SUFFIX) cblas_sbgemmtr.$(SUFFIX) cblas_sbgemm_batch.$(SUFFIX) cblas_sbgemm_batch_strided.$(SUFFIX)
|
||||
CSBEXTOBJS = cblas_sbstobf16.$(SUFFIX) cblas_sbdtobf16.$(SUFFIX) cblas_sbf16tos.$(SUFFIX) cblas_dbf16tod.$(SUFFIX)
|
||||
ifeq ($(ONLY_CBLAS),1)
|
||||
CSBEXTOBJS += sbstobf16.$(SUFFIX) sbdtobf16.$(SUFFIX) sbf16tos.$(SUFFIX) dbf16tod.$(SUFFIX)
|
||||
@@ -338,6 +339,7 @@ endif
|
||||
|
||||
ifeq ($(BUILD_HFLOAT16),1)
|
||||
CSHBLAS3OBJS = cblas_shgemm.$(SUFFIX)
|
||||
CSHBLAS2OBJS = cblas_shgemv.$(SUFFIX)
|
||||
endif
|
||||
|
||||
CDBLAS1OBJS = \
|
||||
@@ -357,7 +359,7 @@ CDBLAS2OBJS = \
|
||||
CDBLAS3OBJS += \
|
||||
cblas_dgemm.$(SUFFIX) cblas_dsymm.$(SUFFIX) cblas_dtrmm.$(SUFFIX) cblas_dtrsm.$(SUFFIX) \
|
||||
cblas_dsyrk.$(SUFFIX) cblas_dsyr2k.$(SUFFIX) cblas_domatcopy.$(SUFFIX) cblas_dimatcopy.$(SUFFIX) \
|
||||
cblas_dgeadd.$(SUFFIX) cblas_dgemmt.$(SUFFIX) cblas_dgemmtr.$(SUFFIX) cblas_dgemm_batch.$(SUFFIX)
|
||||
cblas_dgeadd.$(SUFFIX) cblas_dgemmt.$(SUFFIX) cblas_dgemmtr.$(SUFFIX) cblas_dgemm_batch.$(SUFFIX) cblas_dgemm_batch_strided.$(SUFFIX)
|
||||
|
||||
CCBLAS1OBJS = \
|
||||
cblas_icamax.$(SUFFIX) cblas_icamin.$(SUFFIX) cblas_scasum.$(SUFFIX) cblas_caxpy.$(SUFFIX) \
|
||||
@@ -382,7 +384,7 @@ CCBLAS3OBJS = \
|
||||
cblas_csyrk.$(SUFFIX) cblas_csyr2k.$(SUFFIX) \
|
||||
cblas_chemm.$(SUFFIX) cblas_cherk.$(SUFFIX) cblas_cher2k.$(SUFFIX) \
|
||||
cblas_comatcopy.$(SUFFIX) cblas_cimatcopy.$(SUFFIX)\
|
||||
cblas_cgeadd.$(SUFFIX) cblas_cgemmt.$(SUFFIX) cblas_cgemmtr.$(SUFFIX) cblas_cgemm_batch.$(SUFFIX)
|
||||
cblas_cgeadd.$(SUFFIX) cblas_cgemmt.$(SUFFIX) cblas_cgemmtr.$(SUFFIX) cblas_cgemm_batch.$(SUFFIX) cblas_cgemm_batch_strided.$(SUFFIX)
|
||||
|
||||
CXERBLAOBJ = \
|
||||
cblas_xerbla.$(SUFFIX)
|
||||
@@ -413,7 +415,7 @@ CZBLAS3OBJS = \
|
||||
cblas_zsyrk.$(SUFFIX) cblas_zsyr2k.$(SUFFIX) \
|
||||
cblas_zhemm.$(SUFFIX) cblas_zherk.$(SUFFIX) cblas_zher2k.$(SUFFIX)\
|
||||
cblas_zomatcopy.$(SUFFIX) cblas_zimatcopy.$(SUFFIX) \
|
||||
cblas_zgeadd.$(SUFFIX) cblas_zgemmt.$(SUFFIX) cblas_zgemmtr.$(SUFFIX) cblas_zgemm_batch.$(SUFFIX)
|
||||
cblas_zgeadd.$(SUFFIX) cblas_zgemmt.$(SUFFIX) cblas_zgemmtr.$(SUFFIX) cblas_zgemm_batch.$(SUFFIX) cblas_zgemm_batch_strided.$(SUFFIX)
|
||||
|
||||
|
||||
ifeq ($(SUPPORT_GEMM3M), 1)
|
||||
@@ -441,6 +443,7 @@ SBBLAS1OBJS += $(CSBBLAS1OBJS)
|
||||
SBBLAS2OBJS += $(CSBBLAS2OBJS)
|
||||
SBBLAS3OBJS += $(CSBBLAS3OBJS)
|
||||
SHBLAS3OBJS += $(CSHBLAS3OBJS)
|
||||
SHBLAS2OBJS += $(CSHBLAS2OBJS)
|
||||
DBLAS1OBJS += $(CDBLAS1OBJS)
|
||||
DBLAS2OBJS += $(CDBLAS2OBJS)
|
||||
DBLAS3OBJS += $(CDBLAS3OBJS)
|
||||
@@ -459,7 +462,7 @@ endif
|
||||
BBLASOBJS = $(BBLAS3OBJS) $(BBLAS2OBJS) $(BBLAS1OBJS)
|
||||
SBLASOBJS = $(SBLAS1OBJS) $(SBLAS2OBJS) $(SBLAS3OBJS)
|
||||
SBBLASOBJS = $(SBBLAS1OBJS) $(SBBLAS2OBJS) $(SBBLAS3OBJS)
|
||||
SHBLASOBJS = $(SHBLAS3OBJS)
|
||||
SHBLASOBJS = $(SHBLAS3OBJS) $(SHBLAS2OBJS)
|
||||
DBLASOBJS = $(DBLAS1OBJS) $(DBLAS2OBJS) $(DBLAS3OBJS)
|
||||
QBLASOBJS = $(QBLAS1OBJS) $(QBLAS2OBJS) $(QBLAS3OBJS)
|
||||
CBLASOBJS = $(CBLAS1OBJS) $(CBLAS2OBJS) $(CBLAS3OBJS)
|
||||
@@ -602,7 +605,7 @@ clean ::
|
||||
level1 : $(SBEXTOBJS) $(SBBLAS1OBJS) $(SBLAS1OBJS) $(DBLAS1OBJS) $(QBLAS1OBJS) $(CBLAS1OBJS) $(ZBLAS1OBJS) $(XBLAS1OBJS)
|
||||
$(AR) $(ARFLAGS) -ru $(TOPDIR)/$(LIBNAME) $^
|
||||
|
||||
level2 : $(SBBLAS2OBJS) $(BBLAS2OBJS) $(SBLAS2OBJS) $(DBLAS2OBJS) $(QBLAS2OBJS) $(CBLAS2OBJS) $(ZBLAS2OBJS) $(XBLAS2OBJS)
|
||||
level2 : $(SBBLAS2OBJS) $(BBLAS2OBJS) $(SBLAS2OBJS) $(DBLAS2OBJS) $(QBLAS2OBJS) $(CBLAS2OBJS) $(ZBLAS2OBJS) $(XBLAS2OBJS) $(SHBLAS2OBJS)
|
||||
$(AR) $(ARFLAGS) -ru $(TOPDIR)/$(LIBNAME) $^
|
||||
|
||||
level3 : $(SBBLAS3OBJS) $(BBLAS3OBJ) $(SBLAS3OBJS) $(DBLAS3OBJS) $(QBLAS3OBJS) $(CBLAS3OBJS) $(ZBLAS3OBJS) $(XBLAS3OBJS) $(SHBLAS3OBJS)
|
||||
@@ -1002,6 +1005,11 @@ sbgemv.$(SUFFIX) sbgemv.$(PSUFFIX) : sbgemv.c
|
||||
$(CC) $(CFLAGS) -c $< -o $(@F)
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_HFLOAT16),1)
|
||||
shgemv.$(SUFFIX) shgemv.$(PSUFFIX) : sbgemv.c
|
||||
$(CC) $(CFLAGS) -c $< -o $(@F)
|
||||
endif
|
||||
|
||||
ifndef USE_NETLIB_GEMV
|
||||
sgemv.$(SUFFIX) sgemv.$(PSUFFIX): gemv.c
|
||||
$(CC) -c $(CFLAGS) -o $(@F) $<
|
||||
@@ -1832,6 +1840,11 @@ cblas_sbgemv.$(SUFFIX) cblas_sbgemv.$(PSUFFIX) : sbgemv.c
|
||||
$(CC) -DCBLAS -c $(CFLAGS) $< -o $(@F)
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_HFLOAT16),1)
|
||||
cblas_shgemv.$(SUFFIX) cblas_shgemv.$(PSUFFIX) : sbgemv.c
|
||||
$(CC) -DCBLAS -c $(CFLAGS) $< -o $(@F)
|
||||
endif
|
||||
|
||||
cblas_sgemv.$(SUFFIX) cblas_sgemv.$(PSUFFIX): gemv.c
|
||||
$(CC) -DCBLAS -c $(CFLAGS) -o $(@F) $<
|
||||
|
||||
@@ -2544,6 +2557,21 @@ cblas_cgemm_batch.$(SUFFIX) cblas_cgemm_batch.$(PSUFFIX) : gemm_batch.c ../param
|
||||
cblas_zgemm_batch.$(SUFFIX) cblas_zgemm_batch.$(PSUFFIX) : gemm_batch.c ../param.h
|
||||
$(CC) -c $(CFLAGS) -DCBLAS $< -o $(@F)
|
||||
|
||||
cblas_sbgemm_batch_strided.$(SUFFIX) cblas_sbgemm_batch_strided.$(PSUFFIX) : gemm_batch_strided.c ../param.h
|
||||
$(CC) -c $(CFLAGS) -DCBLAS $< -o $(@F)
|
||||
|
||||
cblas_sgemm_batch_strided.$(SUFFIX) cblas_sgemm_batch_strided.$(PSUFFIX) : gemm_batch_strided.c ../param.h
|
||||
$(CC) -c $(CFLAGS) -DCBLAS $< -o $(@F)
|
||||
|
||||
cblas_dgemm_batch_strided.$(SUFFIX) cblas_dgemm_batch_strided.$(PSUFFIX) : gemm_batch_strided.c ../param.h
|
||||
$(CC) -c $(CFLAGS) -DCBLAS $< -o $(@F)
|
||||
|
||||
cblas_cgemm_batch_strided.$(SUFFIX) cblas_cgemm_batch_strided.$(PSUFFIX) : gemm_batch_strided.c ../param.h
|
||||
$(CC) -c $(CFLAGS) -DCBLAS $< -o $(@F)
|
||||
|
||||
cblas_zgemm_batch_strided.$(SUFFIX) cblas_zgemm_batch_strided.$(PSUFFIX) : gemm_batch_strided.c ../param.h
|
||||
$(CC) -c $(CFLAGS) -DCBLAS $< -o $(@F)
|
||||
|
||||
sbgemm_batch.$(SUFFIX) sbgemm_batch.$(PSUFFIX) : gemm_batch.c ../param.h
|
||||
$(CC) -c $(CFLAGS) -UCBLAS $< -o $(@F)
|
||||
|
||||
@@ -2559,3 +2587,17 @@ cgemm_batch.$(SUFFIX) cgemm_batch.$(PSUFFIX) : gemm_batch.c ../param.h
|
||||
zgemm_batch.$(SUFFIX) zgemm_batch.$(PSUFFIX) : gemm_batch.c ../param.h
|
||||
$(CC) -c $(CFLAGS) -UCBLAS $< -o $(@F)
|
||||
|
||||
sbgemm_batch_strided.$(SUFFIX) sbgemm_batch_strided.$(PSUFFIX) : gemm_batch_strided.c ../param.h
|
||||
$(CC) -c $(CFLAGS) -UCBLAS $< -o $(@F)
|
||||
|
||||
sgemm_batch_strided.$(SUFFIX) sgemm_batch_strided.$(PSUFFIX) : gemm_batch_strided.c ../param.h
|
||||
$(CC) -c $(CFLAGS) -UCBLAS $< -o $(@F)
|
||||
|
||||
dgemm_batch_strided.$(SUFFIX) dgemm_batch_strided.$(PSUFFIX) : gemm_batch_strided.c ../param.h
|
||||
$(CC) -c $(CFLAGS) -UCBLAS $< -o $(@F)
|
||||
|
||||
cgemm_batch_strided.$(SUFFIX) cgemm_batch_strided.$(PSUFFIX) : gemm_batch_strided.c ../param.h
|
||||
$(CC) -c $(CFLAGS) -UCBLAS $< -o $(@F)
|
||||
|
||||
zgemm_batch_strided.$(SUFFIX) zgemm_batch_strided.$(PSUFFIX) : gemm_batch_strided.c ../param.h
|
||||
$(CC) -c $(CFLAGS) -UCBLAS $< -o $(@F)
|
||||
|
||||
+47
-25
@@ -266,6 +266,7 @@ void NAME(char *TRANSA, char *TRANSB,
|
||||
|
||||
int transa, transb, nrowa, nrowb;
|
||||
blasint info;
|
||||
int order = -1;
|
||||
|
||||
char transA, transB;
|
||||
IFLOAT *buffer;
|
||||
@@ -424,30 +425,6 @@ void CNAME(enum CBLAS_ORDER order, enum CBLAS_TRANSPOSE TransA, enum CBLAS_TRANS
|
||||
|
||||
PRINT_DEBUG_CNAME;
|
||||
|
||||
#if !defined(COMPLEX) && !defined(DOUBLE) && !defined(BFLOAT16) && !defined(HFLOAT16)
|
||||
#if defined(ARCH_x86) && (defined(USE_SGEMM_KERNEL_DIRECT)||defined(DYNAMIC_ARCH))
|
||||
#if defined(DYNAMIC_ARCH)
|
||||
if (support_avx512() )
|
||||
#endif
|
||||
if (beta == 0 && alpha == 1.0 && order == CblasRowMajor && TransA == CblasNoTrans && TransB == CblasNoTrans && SGEMM_DIRECT_PERFORMANT(m,n,k)) {
|
||||
SGEMM_DIRECT(m, n, k, a, lda, b, ldb, c, ldc);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(ARCH_ARM64) && (defined(USE_SGEMM_KERNEL_DIRECT)||defined(DYNAMIC_ARCH))
|
||||
#if defined(DYNAMIC_ARCH)
|
||||
if (support_sme1())
|
||||
#endif
|
||||
if (beta == 0 && alpha == 1.0 && order == CblasRowMajor && TransA == CblasNoTrans && TransB == CblasNoTrans) {
|
||||
SGEMM_DIRECT(m, n, k, a, lda, b, ldb, c, ldc);
|
||||
return;
|
||||
}else if (order == CblasRowMajor && TransA == CblasNoTrans && TransB == CblasNoTrans) {
|
||||
SGEMM_DIRECT_ALPHA_BETA(m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef COMPLEX
|
||||
args.alpha = (void *)α
|
||||
args.beta = (void *)β
|
||||
@@ -564,6 +541,40 @@ void CNAME(enum CBLAS_ORDER order, enum CBLAS_TRANSPOSE TransA, enum CBLAS_TRANS
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ((args.m == 0) || (args.n == 0)) return;
|
||||
#if !defined(COMPLEX) && !defined(DOUBLE) && !defined(BFLOAT16) && !defined(HFLOAT16)
|
||||
#if defined(ARCH_x86) && (defined(USE_SGEMM_KERNEL_DIRECT)||defined(DYNAMIC_ARCH))
|
||||
#if defined(DYNAMIC_ARCH)
|
||||
if (support_avx512() )
|
||||
#endif
|
||||
if (order == CblasRowMajor && beta == 0 && alpha == 1.0 && TransA == CblasNoTrans && TransB == CblasNoTrans && SGEMM_DIRECT_PERFORMANT(m,n,k)) {
|
||||
SGEMM_DIRECT(m, n, k, a, lda, b, ldb, c, ldc);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined(ARCH_ARM64) && (defined(USE_SGEMM_KERNEL_DIRECT)||defined(DYNAMIC_ARCH))
|
||||
#if defined(DYNAMIC_ARCH)
|
||||
if (strcmp(gotoblas_corename(), "armv9sme") == 0
|
||||
#if defined(__clang__)
|
||||
|| strcmp(gotoblas_corename(), "vortexm4") == 0
|
||||
#endif
|
||||
)
|
||||
// if (support_sme1())
|
||||
#endif
|
||||
if (order == CblasRowMajor && m==lda && n ==ldb && k==ldc && beta == 0 && alpha == 1.0 && TransA == CblasNoTrans && TransB == CblasNoTrans&& SGEMM_DIRECT_PERFORMANT(m,n,k)) {
|
||||
SGEMM_DIRECT(m, n, k, a, lda, b, ldb, c, ldc);
|
||||
return;
|
||||
}
|
||||
else
|
||||
if (order == CblasRowMajor && m==lda && n==ldb && k==ldc && TransA == CblasNoTrans && TransB == CblasNoTrans&& SGEMM_DIRECT_PERFORMANT(m,n,k)) {
|
||||
SGEMM_DIRECT_ALPHA_BETA(m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && defined(__x86_64__) && defined(BFLOAT16)
|
||||
@@ -587,7 +598,18 @@ void CNAME(enum CBLAS_ORDER order, enum CBLAS_TRANSPOSE TransA, enum CBLAS_TRANS
|
||||
args.m, args.n, args.k, args.lda, args.ldb, args.ldc);
|
||||
#endif
|
||||
|
||||
#if defined(GEMM_GEMV_FORWARD) && !defined(GEMM3M) && !defined(COMPLEX) && !defined(HFLOAT16) && (!defined(BFLOAT16) || (!defined(BGEMM) && defined(SBGEMM_GEMV_FORWARD)) || (defined(BGEMM) && defined(BGEMM_GEMV_FORWARD)))
|
||||
#if (!defined(BFLOAT16) || (!defined(BGEMM) && defined(SBGEMM_GEMV_FORWARD)) || (defined(BGEMM) && defined(BGEMM_GEMV_FORWARD)))
|
||||
#define BFLOAT16_GEMM_GEMV_FORWARD 1
|
||||
#else
|
||||
#define BFLOAT16_GEMM_GEMV_FORWARD 0
|
||||
#endif
|
||||
#if (!defined(HFLOAT16) || (!defined(HGEMM) && defined(SHGEMM_GEMV_FORWARD)) || (defined(HGEMM) && defined(HGEMM_GEMV_FORWARD)))
|
||||
#define HFLOAT16_GEMM_GEMV_FORWARD 1
|
||||
#else
|
||||
#define HFLOAT16_GEMM_GEMV_FORWARD 0
|
||||
#endif
|
||||
|
||||
#if defined(GEMM_GEMV_FORWARD) && !defined(GEMM3M) && !defined(COMPLEX) && HFLOAT16_GEMM_GEMV_FORWARD && BFLOAT16_GEMM_GEMV_FORWARD
|
||||
#if defined(ARCH_ARM64)
|
||||
// The gemv kernels in arm64/{gemv_n.S,gemv_n_sve.c,gemv_t.S,gemv_t_sve.c}
|
||||
// perform poorly in certain circumstances. We use the following boolean
|
||||
|
||||
@@ -0,0 +1,425 @@
|
||||
/*****************************************************************************
|
||||
Copyright (c) 2025, The OpenBLAS Project
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
3. Neither the name of the OpenBLAS project nor the names of
|
||||
its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
**********************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "common.h"
|
||||
|
||||
void openblas_warning(int verbose, const char * msg);
|
||||
|
||||
#ifndef COMPLEX
|
||||
#ifdef XDOUBLE
|
||||
#define ERROR_NAME "QGEMM_BATCH_STRIDED "
|
||||
#elif defined(DOUBLE)
|
||||
#define ERROR_NAME "DGEMM_BATCH_STRIDED "
|
||||
#define GEMM_BATCH_THREAD dgemm_batch_thread
|
||||
#else
|
||||
#define ERROR_NAME "SGEMM_BATCH_STRIDED "
|
||||
#define GEMM_BATCH_THREAD sgemm_batch_thread
|
||||
#endif
|
||||
#else
|
||||
#ifdef XDOUBLE
|
||||
#define ERROR_NAME "XGEMM_BATCH_STRIDED "
|
||||
#elif defined(DOUBLE)
|
||||
#define ERROR_NAME "ZGEMM_BATCH_STRIDED "
|
||||
#define GEMM_BATCH_THREAD zgemm_batch_thread
|
||||
#else
|
||||
#define ERROR_NAME "CGEMM_BATCH_STRIDED "
|
||||
#define GEMM_BATCH_THREAD cgemm_batch_thread
|
||||
#endif
|
||||
#endif
|
||||
static int (*gemm[])(blas_arg_t *, BLASLONG *, BLASLONG *, IFLOAT *, IFLOAT *, BLASLONG) = {
|
||||
GEMM_NN, GEMM_TN, GEMM_RN, GEMM_CN,
|
||||
GEMM_NT, GEMM_TT, GEMM_RT, GEMM_CT,
|
||||
GEMM_NR, GEMM_TR, GEMM_RR, GEMM_CR,
|
||||
GEMM_NC, GEMM_TC, GEMM_RC, GEMM_CC,
|
||||
};
|
||||
|
||||
#if defined(SMALL_MATRIX_OPT) && !defined(GEMM3M) && !defined(XDOUBLE)
|
||||
#define USE_SMALL_MATRIX_OPT 1
|
||||
#else
|
||||
#define USE_SMALL_MATRIX_OPT 0
|
||||
#endif
|
||||
|
||||
#if USE_SMALL_MATRIX_OPT
|
||||
#ifndef DYNAMIC_ARCH
|
||||
#define SMALL_KERNEL_ADDR(table, idx) ((void *)(table[idx]))
|
||||
#else
|
||||
#define SMALL_KERNEL_ADDR(table, idx) ((void *)(*(uintptr_t *)((char *)gotoblas + (size_t)(table[idx]))))
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef COMPLEX
|
||||
static size_t gemm_small_kernel[] = {
|
||||
GEMM_SMALL_KERNEL_NN, GEMM_SMALL_KERNEL_TN, 0, 0,
|
||||
GEMM_SMALL_KERNEL_NT, GEMM_SMALL_KERNEL_TT, 0, 0,
|
||||
};
|
||||
|
||||
|
||||
static size_t gemm_small_kernel_b0[] = {
|
||||
GEMM_SMALL_KERNEL_B0_NN, GEMM_SMALL_KERNEL_B0_TN, 0, 0,
|
||||
GEMM_SMALL_KERNEL_B0_NT, GEMM_SMALL_KERNEL_B0_TT, 0, 0,
|
||||
};
|
||||
|
||||
#define GEMM_SMALL_KERNEL_B0(idx) (int (*)(BLASLONG, BLASLONG, BLASLONG, IFLOAT *, BLASLONG, FLOAT, IFLOAT *, BLASLONG, FLOAT *, BLASLONG)) SMALL_KERNEL_ADDR(gemm_small_kernel_b0, (idx))
|
||||
#define GEMM_SMALL_KERNEL(idx) (int (*)(BLASLONG, BLASLONG, BLASLONG, IFLOAT *, BLASLONG, FLOAT, IFLOAT *, BLASLONG, FLOAT, FLOAT *, BLASLONG)) SMALL_KERNEL_ADDR(gemm_small_kernel, (idx))
|
||||
#else
|
||||
|
||||
static size_t zgemm_small_kernel[] = {
|
||||
GEMM_SMALL_KERNEL_NN, GEMM_SMALL_KERNEL_TN, GEMM_SMALL_KERNEL_RN, GEMM_SMALL_KERNEL_CN,
|
||||
GEMM_SMALL_KERNEL_NT, GEMM_SMALL_KERNEL_TT, GEMM_SMALL_KERNEL_RT, GEMM_SMALL_KERNEL_CT,
|
||||
GEMM_SMALL_KERNEL_NR, GEMM_SMALL_KERNEL_TR, GEMM_SMALL_KERNEL_RR, GEMM_SMALL_KERNEL_CR,
|
||||
GEMM_SMALL_KERNEL_NC, GEMM_SMALL_KERNEL_TC, GEMM_SMALL_KERNEL_RC, GEMM_SMALL_KERNEL_CC,
|
||||
};
|
||||
|
||||
static size_t zgemm_small_kernel_b0[] = {
|
||||
GEMM_SMALL_KERNEL_B0_NN, GEMM_SMALL_KERNEL_B0_TN, GEMM_SMALL_KERNEL_B0_RN, GEMM_SMALL_KERNEL_B0_CN,
|
||||
GEMM_SMALL_KERNEL_B0_NT, GEMM_SMALL_KERNEL_B0_TT, GEMM_SMALL_KERNEL_B0_RT, GEMM_SMALL_KERNEL_B0_CT,
|
||||
GEMM_SMALL_KERNEL_B0_NR, GEMM_SMALL_KERNEL_B0_TR, GEMM_SMALL_KERNEL_B0_RR, GEMM_SMALL_KERNEL_B0_CR,
|
||||
GEMM_SMALL_KERNEL_B0_NC, GEMM_SMALL_KERNEL_B0_TC, GEMM_SMALL_KERNEL_B0_RC, GEMM_SMALL_KERNEL_B0_CC,
|
||||
};
|
||||
|
||||
#define ZGEMM_SMALL_KERNEL(idx) (int (*)(BLASLONG, BLASLONG, BLASLONG, FLOAT *, BLASLONG, FLOAT , FLOAT, FLOAT *, BLASLONG, FLOAT , FLOAT, FLOAT *, BLASLONG)) SMALL_KERNEL_ADDR(zgemm_small_kernel, (idx))
|
||||
#define ZGEMM_SMALL_KERNEL_B0(idx) (int (*)(BLASLONG, BLASLONG, BLASLONG, FLOAT *, BLASLONG, FLOAT , FLOAT, FLOAT *, BLASLONG, FLOAT *, BLASLONG)) SMALL_KERNEL_ADDR(zgemm_small_kernel_b0, (idx))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CBLAS
|
||||
void NAME(char *transa, char *transb,
|
||||
blasint * M, blasint * N, blasint * K,
|
||||
FLOAT * Alpha,
|
||||
IFLOAT * a, blasint * Lda,
|
||||
blasint * stride_a,
|
||||
IFLOAT *b, blasint * Ldb,
|
||||
blasint * stride_b,
|
||||
FLOAT * Beta,
|
||||
FLOAT * c, blasint * Ldc, blasint * stride_c, blasint * matcount) {
|
||||
|
||||
char ta = *transa;
|
||||
char tb = *transb;
|
||||
blasint count = *matcount;
|
||||
blasint stridea= *stride_a;
|
||||
blasint strideb= *stride_b;
|
||||
blasint stridec= *stride_c;
|
||||
blasint m=*M;
|
||||
blasint n=*N;
|
||||
blasint k=*K;
|
||||
blasint lda=*Lda;
|
||||
blasint ldb=*Ldb;
|
||||
blasint ldc=*Ldc;
|
||||
#if !defined(COMPLEX)
|
||||
FLOAT alpha=*Alpha;
|
||||
FLOAT beta=*Beta;
|
||||
#else
|
||||
FLOAT *alpha=Alpha;
|
||||
FLOAT *beta=Beta;
|
||||
#endif
|
||||
#else
|
||||
|
||||
void CNAME(enum CBLAS_ORDER order, enum CBLAS_TRANSPOSE transa, enum CBLAS_TRANSPOSE transb,
|
||||
blasint m, blasint n, blasint k,
|
||||
#ifndef COMPLEX
|
||||
FLOAT alpha,
|
||||
IFLOAT * a, blasint lda, blasint stridea,
|
||||
IFLOAT * b, blasint ldb, blasint strideb,
|
||||
FLOAT beta,
|
||||
FLOAT * c, blasint ldc, blasint stridec, blasint count) {
|
||||
#else
|
||||
void * valpha,
|
||||
void * va, blasint lda, blasint stridea,
|
||||
void * vb, blasint ldb, blasint strideb,
|
||||
void * vbeta,
|
||||
void * vc, blasint ldc, blasint stridec, blasint count) {
|
||||
|
||||
FLOAT * alpha=(FLOAT *)valpha;
|
||||
FLOAT * beta=(FLOAT *)vbeta;
|
||||
FLOAT * a=(FLOAT*)va;
|
||||
FLOAT * b=(FLOAT*)vb;
|
||||
FLOAT * c=(FLOAT*)vc;
|
||||
#endif
|
||||
#endif
|
||||
BLASLONG group_m, group_n, group_k;
|
||||
BLASLONG group_lda, group_ldb, group_ldc;
|
||||
|
||||
blas_arg_t * args_array=NULL;
|
||||
|
||||
int mode=0, group_mode=0;
|
||||
|
||||
blasint i=0;
|
||||
|
||||
int group_transa, group_transb;
|
||||
BLASLONG group_nrowa, group_nrowb;
|
||||
blasint info;
|
||||
|
||||
void * group_routine=NULL;
|
||||
#ifdef SMALL_MATRIX_OPT
|
||||
void * group_small_matrix_opt_routine=NULL;
|
||||
#endif
|
||||
|
||||
#if defined (SMP) || defined(SMALL_MATRIX_OPT)
|
||||
double MNK;
|
||||
#endif
|
||||
|
||||
PRINT_DEBUG_CNAME;
|
||||
|
||||
args_array=(blas_arg_t *)malloc(count * sizeof(blas_arg_t));
|
||||
|
||||
if(args_array == NULL){
|
||||
openblas_warning(0, "memory alloc failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef SMP
|
||||
#ifndef COMPLEX
|
||||
#ifdef XDOUBLE
|
||||
mode = BLAS_XDOUBLE | BLAS_REAL;
|
||||
#elif defined(DOUBLE)
|
||||
mode = BLAS_DOUBLE | BLAS_REAL;
|
||||
#else
|
||||
mode = BLAS_SINGLE | BLAS_REAL;
|
||||
#endif
|
||||
#else
|
||||
#ifdef XDOUBLE
|
||||
mode = BLAS_XDOUBLE | BLAS_COMPLEX;
|
||||
#elif defined(DOUBLE)
|
||||
mode = BLAS_DOUBLE | BLAS_COMPLEX;
|
||||
#else
|
||||
mode = BLAS_SINGLE | BLAS_COMPLEX;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
for(i=0; i<count; i++) {
|
||||
|
||||
group_m = group_n = group_k = 0;
|
||||
group_lda = group_ldb = group_ldc = 0;
|
||||
group_transa = -1;
|
||||
group_transb = -1;
|
||||
info = 0;
|
||||
|
||||
#if defined(CBLAS)
|
||||
if (order == CblasColMajor) {
|
||||
group_m = m;
|
||||
group_n = n;
|
||||
group_k = k;
|
||||
|
||||
|
||||
if (transa == CblasNoTrans) group_transa = 0;
|
||||
if (transa == CblasTrans) group_transa = 1;
|
||||
#ifndef COMPLEX
|
||||
if (transa == CblasConjNoTrans) group_transa = 0;
|
||||
if (transa == CblasConjTrans) group_transa = 1;
|
||||
#else
|
||||
if (transa == CblasConjNoTrans) group_transa = 2;
|
||||
if (transa == CblasConjTrans) group_transa = 3;
|
||||
#endif
|
||||
if (transb == CblasNoTrans) group_transb = 0;
|
||||
if (transb == CblasTrans) group_transb = 1;
|
||||
#ifndef COMPLEX
|
||||
if (transb == CblasConjNoTrans) group_transb = 0;
|
||||
if (transb == CblasConjTrans) group_transb = 1;
|
||||
#else
|
||||
if (transb == CblasConjNoTrans) group_transb = 2;
|
||||
if (transb == CblasConjTrans) group_transb = 3;
|
||||
#endif
|
||||
group_nrowa = group_m;
|
||||
if (group_transa & 1) group_nrowa = group_k;
|
||||
group_nrowb = group_k;
|
||||
if (group_transb & 1) group_nrowb = group_n;
|
||||
|
||||
info=-1;
|
||||
|
||||
if (group_ldc < group_m) info = 13;
|
||||
if (group_ldb < group_nrowb) info = 10;
|
||||
if (group_lda < group_nrowa) info = 8;
|
||||
if (group_k < 0) info = 5;
|
||||
if (group_n < 0) info = 4;
|
||||
if (group_m < 0) info = 3;
|
||||
if (group_transb < 0) info = 2;
|
||||
if (group_transa < 0) info = 1;
|
||||
|
||||
}else if (order == CblasRowMajor) {
|
||||
|
||||
group_m = n;
|
||||
group_n = m;
|
||||
group_k = k;
|
||||
|
||||
group_lda = ldb;
|
||||
group_ldb = lda;
|
||||
group_ldc = ldc;
|
||||
|
||||
if (transb == CblasNoTrans) group_transa = 0;
|
||||
if (transb == CblasTrans) group_transa = 1;
|
||||
#ifndef COMPLEX
|
||||
if (transb == CblasConjNoTrans) group_transa = 0;
|
||||
if (transb == CblasConjTrans) group_transa = 1;
|
||||
#else
|
||||
if (transb == CblasConjNoTrans) group_transa = 2;
|
||||
if (transb == CblasConjTrans) group_transa = 3;
|
||||
#endif
|
||||
if (transa == CblasNoTrans) group_transb = 0;
|
||||
if (transa == CblasTrans) group_transb = 1;
|
||||
#ifndef COMPLEX
|
||||
if (transa == CblasConjNoTrans) group_transb = 0;
|
||||
if (transa == CblasConjTrans) group_transb = 1;
|
||||
#else
|
||||
if (transa == CblasConjNoTrans) group_transb = 2;
|
||||
if (transa == CblasConjTrans) group_transb = 3;
|
||||
#endif
|
||||
|
||||
#else
|
||||
group_m = m;
|
||||
group_n = n;
|
||||
group_k = k;
|
||||
|
||||
group_lda = lda;
|
||||
group_ldb = ldb;
|
||||
group_ldc = ldc;
|
||||
|
||||
if (tb == 'N') group_transa = 0;
|
||||
if (tb == 'T') group_transa = 1;
|
||||
#ifndef COMPLEX
|
||||
if (tb == 'C') group_transa = 1;
|
||||
#else
|
||||
if (tb == 'C') group_transa = 3;
|
||||
#endif
|
||||
if (ta == 'N') group_transb = 0;
|
||||
if (ta == 'T') group_transb = 1;
|
||||
#ifndef COMPLEX
|
||||
if (ta == 'C') group_transb = 1;
|
||||
#else
|
||||
if (ta == 'C') group_transb = 3;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
group_nrowa = group_m;
|
||||
if (group_transa & 1) group_nrowa = group_k;
|
||||
group_nrowb = group_k;
|
||||
if (group_transb & 1) group_nrowb = group_n;
|
||||
|
||||
info=-1;
|
||||
|
||||
if (group_ldc < group_m) info = 13;
|
||||
if (group_ldb < group_nrowb) info = 10;
|
||||
if (group_lda < group_nrowa) info = 8;
|
||||
if (group_k < 0) info = 5;
|
||||
if (group_n < 0) info = 4;
|
||||
if (group_m < 0) info = 3;
|
||||
if (group_transb < 0) info = 2;
|
||||
if (group_transa < 0) info = 1;
|
||||
#if defined(CBLAS)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (info >= 0) {
|
||||
BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
|
||||
free(args_array);
|
||||
return;
|
||||
}
|
||||
|
||||
if (group_m == 0 || group_n == 0) continue;
|
||||
|
||||
group_mode=mode;
|
||||
|
||||
#if defined(SMP) || defined(SMALL_MATRIX_OPT)
|
||||
MNK = (double) group_m * (double) group_n * (double) group_k;
|
||||
#endif
|
||||
|
||||
#ifdef SMALL_MATRIX_OPT
|
||||
if (MNK <= 100.0*100.0*100.0){
|
||||
group_routine=NULL;
|
||||
#if !defined(COMPLEX)
|
||||
if(beta == 0.0){
|
||||
group_mode=mode | BLAS_SMALL_B0_OPT;
|
||||
group_small_matrix_opt_routine=(void *)(gemm_small_kernel_b0[(group_transb<<2)|group_transa]);
|
||||
}else{
|
||||
group_mode=mode | BLAS_SMALL_OPT;
|
||||
group_small_matrix_opt_routine=(void *)(gemm_small_kernel[(group_transb<<2)|group_transa]);
|
||||
}
|
||||
#else
|
||||
if(beta[0] == 0.0 && beta[1] == 0.0){
|
||||
group_mode=mode | BLAS_SMALL_B0_OPT;
|
||||
group_small_matrix_opt_routine=(void *)(zgemm_small_kernel_b0[(group_transb<<2)|group_transa]);
|
||||
}else{
|
||||
group_mode=mode | BLAS_SMALL_OPT;
|
||||
group_small_matrix_opt_routine=(void *)(zgemm_small_kernel[(group_transb<<2)|group_transa]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}else{
|
||||
#endif
|
||||
group_routine=(void*)(gemm[(group_transb<<2)|group_transa]);
|
||||
#ifdef SMALL_MATRIX_OPT
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
args_array[i].m=group_m;
|
||||
args_array[i].n=group_n;
|
||||
args_array[i].k=group_k;
|
||||
args_array[i].lda=group_lda;
|
||||
args_array[i].ldb=group_ldb;
|
||||
args_array[i].ldc=group_ldc;
|
||||
args_array[i].alpha=α
|
||||
args_array[i].beta=β
|
||||
|
||||
#if defined(CBLAS)
|
||||
if (order == CblasColMajor) {
|
||||
args_array[i].a=&(a[i*stridea]);
|
||||
args_array[i].b=&(b[i*strideb]);
|
||||
}else if(order == CblasRowMajor){
|
||||
args_array[i].a=&(b[i*strideb]);
|
||||
args_array[i].b=&(a[i*stridea]);
|
||||
}
|
||||
#else
|
||||
args_array[i].a=&(a[i*stridea]);
|
||||
args_array[i].b=&(b[i*strideb]);
|
||||
#endif
|
||||
|
||||
args_array[i].c= &c[i*stridec];
|
||||
|
||||
args_array[i].routine_mode=group_mode;
|
||||
args_array[i].routine=group_routine;
|
||||
#ifdef SMALL_MATRIX_OPT
|
||||
if (!group_routine)
|
||||
args_array[i].routine=group_small_matrix_opt_routine;
|
||||
#endif
|
||||
}
|
||||
|
||||
if(count>0) {
|
||||
GEMM_BATCH_THREAD(args_array,count);
|
||||
}
|
||||
|
||||
free(args_array);
|
||||
}
|
||||
+9
-5
@@ -1,4 +1,5 @@
|
||||
/*********************************************************************/
|
||||
/* Copyright 2025 The OpenBLAS Project */
|
||||
/* Copyright 2009, 2010 The University of Texas at Austin. */
|
||||
/* All rights reserved. */
|
||||
/* */
|
||||
@@ -81,9 +82,12 @@ static inline int get_gemv_optimal_nthreads_neoversev1(BLASLONG MN, int ncpu) {
|
||||
: (MN < 1050625L) ? MIN(ncpu, 40)
|
||||
: ncpu;
|
||||
#else
|
||||
return (MN < 25600L) ? 1
|
||||
return
|
||||
(MN < 25600L) ? 1
|
||||
: (MN < 63001L) ? MIN(ncpu, 4)
|
||||
: (MN < 459684L) ? MIN(ncpu, 16)
|
||||
: (MN < 202500L) ? MIN(ncpu, 8)
|
||||
: (MN < 806404L) ? MIN(ncpu, 16)
|
||||
: (MN < 1638400L) ? MIN(ncpu, 32)
|
||||
: ncpu;
|
||||
#endif
|
||||
}
|
||||
@@ -93,9 +97,9 @@ static inline int get_gemv_optimal_nthreads_neoversev1(BLASLONG MN, int ncpu) {
|
||||
static inline int get_gemv_optimal_nthreads_neoversev2(BLASLONG MN, int ncpu) {
|
||||
return
|
||||
MN < 24964L ? 1
|
||||
: MN < 65536L ? MIN(ncpu, 8)
|
||||
: MN < 262144L ? MIN(ncpu, 32)
|
||||
: MN < 1638400L ? MIN(ncpu, 64)
|
||||
: MN < 145924L ? MIN(ncpu, 8)
|
||||
: MN < 692224L ? MIN(ncpu, 16)
|
||||
: MN < 1638400L ? MIN(ncpu, 32)
|
||||
: ncpu;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -48,6 +48,10 @@
|
||||
#define GEMV_THREAD_N bgemv_thread_n
|
||||
#define GEMV_THREAD_T bgemv_thread_t
|
||||
#define ERROR_NAME "BGEMV "
|
||||
#elif defined(HFLOAT16)
|
||||
#define GEMV_THREAD_N shgemv_thread_n
|
||||
#define GEMV_THREAD_T shgemv_thread_t
|
||||
#define ERROR_NAME "SHGEMV "
|
||||
#else
|
||||
#define GEMV_THREAD_N sbgemv_thread_n
|
||||
#define GEMV_THREAD_T sbgemv_thread_t
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ void CNAME(blasint n, FLOAT alpha, FLOAT *x, blasint incx){
|
||||
float alpha_float;
|
||||
SBF16TOS_K(1, &alpha, 1, &alpha_float, 1);
|
||||
#else
|
||||
float alpha_float = alpha;
|
||||
FLOAT alpha_float = alpha;
|
||||
#endif
|
||||
|
||||
if (alpha_float == ONE) return;
|
||||
|
||||
@@ -97,6 +97,9 @@
|
||||
#define GEMM_MULTITHREAD_THRESHOLD 4
|
||||
#endif
|
||||
|
||||
#ifdef DYNAMIC_ARCH
|
||||
extern char* gotoblas_corename(void);
|
||||
#endif
|
||||
|
||||
#ifdef SMP
|
||||
#ifndef COMPLEX
|
||||
@@ -371,6 +374,28 @@ void CNAME(enum CBLAS_ORDER order, enum CBLAS_SIDE Side, enum CBLAS_UPLO Uplo,
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(COMPLEX) && !defined(DOUBLE) && !defined(BFLOAT16) && !defined(HFLOAT16)
|
||||
#if defined(ARCH_ARM64) && (defined(USE_SSYMM_KERNEL_DIRECT)||defined(DYNAMIC_ARCH))
|
||||
#if defined(DYNAMIC_ARCH)
|
||||
if (strcmp(gotoblas_corename(), "armv9sme") == 0
|
||||
#if defined(__clang__)
|
||||
|| strcmp(gotoblas_corename(), "vortexm4") == 0
|
||||
#endif
|
||||
)
|
||||
#endif
|
||||
if (args.m == 0 || args.n == 0) return;
|
||||
if (order == CblasRowMajor && m == lda && n == ldb && n == ldc)
|
||||
{
|
||||
if (Side == CblasLeft && Uplo == CblasUpper) {
|
||||
SSYMM_DIRECT_ALPHA_BETA_LU(m, n, alpha, a, lda, b, ldb, beta, c, ldc); return;
|
||||
}
|
||||
else if (Side == CblasLeft && Uplo == CblasLower) {
|
||||
SSYMM_DIRECT_ALPHA_BETA_LL(m, n, alpha, a, lda, b, ldb, beta, c, ldc); return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
if (args.m == 0 || args.n == 0) return;
|
||||
|
||||
+38
-1
@@ -345,9 +345,46 @@ void CNAME(enum CBLAS_ORDER order, enum CBLAS_UPLO Uplo, enum CBLAS_TRANSPOSE Tr
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.n == 0) return;
|
||||
|
||||
#ifdef DYNAMIC_ARCH
|
||||
extern char* gotoblas_corename(void);
|
||||
#endif
|
||||
|
||||
#if !defined(COMPLEX) && !defined(DOUBLE) && !defined(BFLOAT16) && !defined(HFLOAT16)
|
||||
#if defined(ARCH_ARM64) && (defined(USE_SSYR2K_KERNEL_DIRECT)||defined(DYNAMIC_ARCH))
|
||||
#if defined(DYNAMIC_ARCH)
|
||||
if (strcmp(gotoblas_corename(), "armv9sme") == 0
|
||||
#if defined(__clang__)
|
||||
|| strcmp(gotoblas_corename(), "vortexm4") == 0
|
||||
#endif
|
||||
)
|
||||
#endif
|
||||
if (order == CblasRowMajor && n == ldc) {
|
||||
if (Trans == CblasNoTrans && k == lda && k == ldb) {
|
||||
if (Uplo == CblasUpper) {
|
||||
SSYR2K_DIRECT_ALPHA_BETA_UN(n, k, alpha, a, lda, b, ldb, beta, c, ldc);
|
||||
return;
|
||||
}else if (Uplo == CblasLower) {
|
||||
SSYR2K_DIRECT_ALPHA_BETA_LN(n, k, alpha, a, lda, b, ldb, beta, c, ldc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (Trans == CblasTrans && n == lda && n ==ldb) {
|
||||
if (Uplo == CblasUpper) {
|
||||
SSYR2K_DIRECT_ALPHA_BETA_UT(n, k, alpha, a, lda, b, ldb, beta, c, ldc);
|
||||
return;
|
||||
}else if (Uplo == CblasLower) {
|
||||
SSYR2K_DIRECT_ALPHA_BETA_LT(n, k, alpha, a, lda, b, ldb, beta, c, ldc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
if (args.n == 0) return;
|
||||
|
||||
IDEBUG_START;
|
||||
|
||||
|
||||
+27
-1
@@ -339,9 +339,35 @@ double NNK;
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.n == 0) return;
|
||||
|
||||
#ifdef DYNAMIC_ARCH
|
||||
extern char* gotoblas_corename(void);
|
||||
#endif
|
||||
|
||||
#if !defined(COMPLEX) && !defined(DOUBLE) && !defined(BFLOAT16) && !defined(HFLOAT16)
|
||||
#if defined(ARCH_ARM64) && (defined(USE_SSYRK_KERNEL_DIRECT)||defined(DYNAMIC_ARCH))
|
||||
#if defined(DYNAMIC_ARCH)
|
||||
if (strcmp(gotoblas_corename(), "armv9sme") == 0
|
||||
#if defined(__clang__)
|
||||
|| strcmp(gotoblas_corename(), "vortexm4") == 0
|
||||
#endif
|
||||
)
|
||||
#endif
|
||||
if (order == CblasRowMajor && n == ldc) {
|
||||
if (Trans == CblasNoTrans && k == lda) {
|
||||
(Uplo == CblasUpper ? SSYRK_DIRECT_ALPHA_BETA_UN : SSYRK_DIRECT_ALPHA_BETA_LN)(n, k, alpha, a, lda, beta, c, ldc);
|
||||
return;
|
||||
} else if (Trans == CblasTrans && n == lda){
|
||||
(Uplo == CblasUpper ? SSYRK_DIRECT_ALPHA_BETA_UT : SSYRK_DIRECT_ALPHA_BETA_LT)(n, k, alpha, a, lda, beta, c, ldc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
if (args.n == 0) return;
|
||||
|
||||
IDEBUG_START;
|
||||
|
||||
|
||||
@@ -87,6 +87,10 @@
|
||||
#define SMP_FACTOR 128
|
||||
#endif
|
||||
|
||||
#ifdef DYNAMIC_ARCH
|
||||
extern char* gotoblas_corename(void);
|
||||
#endif
|
||||
|
||||
static int (*trsm[])(blas_arg_t *, BLASLONG *, BLASLONG *, FLOAT *, FLOAT *, BLASLONG) = {
|
||||
#ifndef TRMM
|
||||
TRSM_LNUU, TRSM_LNUN, TRSM_LNLU, TRSM_LNLN,
|
||||
@@ -355,6 +359,27 @@ void CNAME(enum CBLAS_ORDER order,
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(COMPLEX) && !defined(DOUBLE) && !defined(BFLOAT16) && !defined(HFLOAT16)
|
||||
#if defined(ARCH_ARM64) && (defined(USE_STRMM_KERNEL_DIRECT)||defined(DYNAMIC_ARCH))
|
||||
#if defined(DYNAMIC_ARCH)
|
||||
if (strcmp(gotoblas_corename(), "armv9sme") == 0
|
||||
#if defined(__clang__)
|
||||
|| strcmp(gotoblas_corename(), "vortexm4") == 0
|
||||
#endif
|
||||
)
|
||||
#endif
|
||||
if (args.m == 0 || args.n == 0) return;
|
||||
if (order == CblasRowMajor && Diag == CblasNonUnit && Side == CblasLeft && m == lda && n == ldb) {
|
||||
if (Trans == CblasNoTrans) {
|
||||
(Uplo == CblasUpper ? STRMM_DIRECT_LNUN : STRMM_DIRECT_LNLN)(m, n, alpha, a, lda, b, ldb);
|
||||
} else if (Trans == CblasTrans) {
|
||||
(Uplo == CblasUpper ? STRMM_DIRECT_LTUN : STRMM_DIRECT_LTLN)(m, n, alpha, a, lda, b, ldb);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
if ((args.m == 0) || (args.n == 0)) return;
|
||||
|
||||
+4
-1
@@ -177,7 +177,10 @@ void CNAME(enum CBLAS_ORDER order, enum CBLAS_UPLO Uplo, blasint n, FLOAT alpha,
|
||||
buffer = (FLOAT *)blas_memory_alloc(1);
|
||||
|
||||
#ifdef SMP
|
||||
nthreads = num_cpu_avail(2);
|
||||
if (n < 100)
|
||||
nthreads = 1;
|
||||
else
|
||||
nthreads = num_cpu_avail(2);
|
||||
|
||||
if (nthreads == 1) {
|
||||
#endif
|
||||
|
||||
+4
-1
@@ -186,7 +186,10 @@ void CNAME(enum CBLAS_ORDER order, enum CBLAS_UPLO Uplo, blasint n, void *VALPHA
|
||||
buffer = (FLOAT *)blas_memory_alloc(1);
|
||||
|
||||
#ifdef SMP
|
||||
nthreads = num_cpu_avail(2);
|
||||
if (n < 100)
|
||||
nthreads = 1;
|
||||
else
|
||||
nthreads = num_cpu_avail(2);
|
||||
|
||||
if (nthreads == 1) {
|
||||
#endif
|
||||
|
||||
+4
-1
@@ -175,7 +175,10 @@ void CNAME(enum CBLAS_ORDER order,
|
||||
buffer = (FLOAT *)blas_memory_alloc(1);
|
||||
|
||||
#ifdef SMP
|
||||
nthreads = num_cpu_avail(2);
|
||||
if (n < 100)
|
||||
nthreads = 1;
|
||||
else
|
||||
nthreads = num_cpu_avail(2);
|
||||
|
||||
if (nthreads == 1) {
|
||||
#endif
|
||||
|
||||
+4
-1
@@ -187,7 +187,10 @@ void CNAME(enum CBLAS_ORDER order,
|
||||
buffer = (FLOAT *)blas_memory_alloc(1);
|
||||
|
||||
#ifdef SMP
|
||||
nthreads = num_cpu_avail(2);
|
||||
if (n < 100)
|
||||
nthreads = 1;
|
||||
else
|
||||
nthreads = num_cpu_avail(2);
|
||||
|
||||
if (nthreads == 1) {
|
||||
#endif
|
||||
|
||||
+64
-3
@@ -228,6 +228,10 @@ function (build_core TARGET_CORE KDIR TSUFFIX KERNEL_DEFINITIONS)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SBGEMVNKERNEL}" "" "gemv_n" false "" "" false "BFLOAT16")
|
||||
GenerateNamedObjects("${KERNELDIR}/${SBGEMVTKERNEL}" "" "gemv_t" false "" "" false "BFLOAT16")
|
||||
endif ()
|
||||
if (BUILD_HFLOAT16)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SHGEMVNKERNEL}" "" "gemv_n" false "" "" false "HFLOAT16")
|
||||
GenerateNamedObjects("${KERNELDIR}/${SHGEMVTKERNEL}" "" "gemv_t" false "" "" false "HFLOAT16")
|
||||
endif ()
|
||||
# Makefile.L3
|
||||
set(USE_TRMM false)
|
||||
string(TOUPPER ${TARGET_CORE} UC_TARGET_CORE)
|
||||
@@ -237,11 +241,27 @@ function (build_core TARGET_CORE KDIR TSUFFIX KERNEL_DEFINITIONS)
|
||||
if (ZARCH OR (UC_TARGET_CORE MATCHES POWER8) OR (UC_TARGET_CORE MATCHES POWER9) OR (UC_TARGET_CORE MATCHES POWER10))
|
||||
set(USE_TRMM true)
|
||||
endif ()
|
||||
set(USE_DIRECT_STRMM false)
|
||||
if (ARM64)
|
||||
set(USE_DIRECT_STRMM true)
|
||||
endif()
|
||||
set(USE_DIRECT_SSYRK false)
|
||||
if (ARM64)
|
||||
set(USE_DIRECT_SSYRK true)
|
||||
endif()
|
||||
set(USE_DIRECT_SSYR2K false)
|
||||
if (ARM64)
|
||||
set(USE_DIRECT_SSYR2K true)
|
||||
endif()
|
||||
set(USE_DIRECT_SGEMM false)
|
||||
if (X86_64 OR ARM64)
|
||||
set(USE_DIRECT_SGEMM true)
|
||||
endif()
|
||||
if (UC_TARGET_CORE MATCHES ARMV9SME)
|
||||
set(USE_DIRECT_SSYMM false)
|
||||
if (ARM64)
|
||||
set(USE_DIRECT_SSYMM true)
|
||||
endif()
|
||||
if (UC_TARGET_CORE MATCHES ARMV9SME OR UC_TARGET_CORE MATCHES VORTEXM4)
|
||||
set (HAVE_SME true)
|
||||
endif ()
|
||||
|
||||
@@ -254,19 +274,59 @@ function (build_core TARGET_CORE KDIR TSUFFIX KERNEL_DEFINITIONS)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SGEMMDIRECTKERNEL}" "" "gemm_direct" false "" "" false SINGLE)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SGEMMDIRECTPERFORMANT}" "" "gemm_direct_performant" false "" "" false SINGLE)
|
||||
elseif (ARM64)
|
||||
set (SGEMMDIRECTPERFORMANT sgemm_direct_performant.c)
|
||||
set (SGEMMDIRECTKERNEL sgemm_direct_arm64_sme1.c)
|
||||
set (SGEMMDIRECTKERNEL_ALPHA_BETA sgemm_direct_alpha_beta_arm64_sme1.c)
|
||||
set (SGEMMDIRECTSMEKERNEL sgemm_direct_sme1.S)
|
||||
set (SGEMMDIRECTSMEKERNEL sgemm_direct_sme1_2VLx2VL.S)
|
||||
set (SGEMMDIRECTPREKERNEL sgemm_direct_sme1_preprocess.S)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SGEMMDIRECTPERFORMANT}" "" "gemm_direct_performant" false "" "" false SINGLE)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SGEMMDIRECTKERNEL}" "" "gemm_direct" false "" "" false SINGLE)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SGEMMDIRECTKERNEL_ALPHA_BETA}" "" "gemm_direct_alpha_beta" false "" "" false SINGLE)
|
||||
if (HAVE_SME)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SGEMMDIRECTSMEKERNEL}" "" "gemm_direct_sme1" false "" "" false SINGLE)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SGEMMDIRECTSMEKERNEL}" "" "gemm_direct_sme1_2VLx2VL" false "" "" false SINGLE)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SGEMMDIRECTPREKERNEL}" "" "gemm_direct_sme1_preprocess" false "" "" false SINGLE)
|
||||
endif ()
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
if (USE_DIRECT_SSYMM)
|
||||
if (ARM64)
|
||||
set (SSYMMDIRECTKERNEL_ALPHA_BETA ssymm_direct_alpha_beta_arm64_sme1.c)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SSYMMDIRECTKERNEL_ALPHA_BETA}" "" "symm_direct_alpha_betaLU" false "" "" false SINGLE)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SSYMMDIRECTKERNEL_ALPHA_BETA}" "" "symm_direct_alpha_betaLL" false "" "" false SINGLE)
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
if (USE_DIRECT_STRMM)
|
||||
if (ARM64)
|
||||
set (STRMMDIRECTKERNEL strmm_direct_arm64_sme1.c)
|
||||
GenerateNamedObjects("${KERNELDIR}/${STRMMDIRECTKERNEL}" "" "trmm_direct_LNUN" false "" "" false SINGLE)
|
||||
GenerateNamedObjects("${KERNELDIR}/${STRMMDIRECTKERNEL}" "" "trmm_direct_LNLN" false "" "" false SINGLE)
|
||||
GenerateNamedObjects("${KERNELDIR}/${STRMMDIRECTKERNEL}" "" "trmm_direct_LTUN" false "" "" false SINGLE)
|
||||
GenerateNamedObjects("${KERNELDIR}/${STRMMDIRECTKERNEL}" "" "trmm_direct_LTLN" false "" "" false SINGLE)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (USE_DIRECT_SSYRK)
|
||||
if (ARM64)
|
||||
set (SSYRKDIRECTKERNEL_ALPHA_BETA ssyrk_direct_alpha_beta_arm64_sme1.c)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SSYRKDIRECTKERNEL_ALPHA_BETA}" "" "syrk_direct_alpha_betaUN" false "" "" false SINGLE)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SSYRKDIRECTKERNEL_ALPHA_BETA}" "" "syrk_direct_alpha_betaUT" false "" "" false SINGLE)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SSYRKDIRECTKERNEL_ALPHA_BETA}" "" "syrk_direct_alpha_betaLN" false "" "" false SINGLE)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SSYRKDIRECTKERNEL_ALPHA_BETA}" "" "syrk_direct_alpha_betaLT" false "" "" false SINGLE)
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
if (USE_DIRECT_SSYR2K)
|
||||
if (ARM64)
|
||||
set (SSYR2KDIRECTKERNEL_ALPHA_BETA ssyr2k_direct_alpha_beta_arm64_sme1.c)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SSYR2KDIRECTKERNEL_ALPHA_BETA}" "" "syr2k_direct_alpha_betaUN" false "" "" false SINGLE)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SSYR2KDIRECTKERNEL_ALPHA_BETA}" "" "syr2k_direct_alpha_betaUT" false "" "" false SINGLE)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SSYR2KDIRECTKERNEL_ALPHA_BETA}" "" "syr2k_direct_alpha_betaLN" false "" "" false SINGLE)
|
||||
GenerateNamedObjects("${KERNELDIR}/${SSYR2KDIRECTKERNEL_ALPHA_BETA}" "" "syr2k_direct_alpha_betaLT" false "" "" false SINGLE)
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
foreach (float_type SINGLE DOUBLE)
|
||||
string(SUBSTRING ${float_type} 0 1 float_char)
|
||||
GenerateNamedObjects("${KERNELDIR}/${${float_char}GEMMKERNEL}" "" "gemm_kernel" false "" "" false ${float_type})
|
||||
@@ -442,6 +502,7 @@ function (build_core TARGET_CORE KDIR TSUFFIX KERNEL_DEFINITIONS)
|
||||
set(TRMM_KERNEL "${${float_char}GEMMKERNEL}")
|
||||
endif ()
|
||||
|
||||
|
||||
if (${float_type} STREQUAL "COMPLEX" OR ${float_type} STREQUAL "ZCOMPLEX")
|
||||
|
||||
# just enumerate all these. there is an extra define for these indicating which side is a conjugate (e.g. CN NC NN) that I don't really want to work into GenerateCombinationObjects
|
||||
|
||||
+23
-1
@@ -27,7 +27,29 @@ endif
|
||||
|
||||
ifdef TARGET_CORE
|
||||
ifeq ($(TARGET_CORE), ARMV9SME)
|
||||
override CFLAGS += -DBUILD_KERNEL -DTABLE_NAME=gotoblas_$(TARGET_CORE) -DHAVE_SME -march=armv9-a+sve2+sme
|
||||
override CFLAGS += -DBUILD_KERNEL -DTABLE_NAME=gotoblas_$(TARGET_CORE) -march=armv9-a+sve2+sme
|
||||
ifdef OS_WINDOWS
|
||||
ifeq ($(C_COMPILER), CLANG)
|
||||
override CFLAGS += --aarch64-stack-hazard-size=0
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_CORE), VORTEXM4)
|
||||
ifeq ($(C_COMPILER), GCC)
|
||||
override CFLAGS += -DBUILD_KERNEL -DTABLE_NAME=gotoblas_$(TARGET_CORE) -UHAVE_SME -march=armv8.4-a
|
||||
else
|
||||
ifeq ($(APPLECLANG),1)
|
||||
override CFLAGS += -DBUILD_KERNEL -DTABLE_NAME=gotoblas_$(TARGET_CORE) -march=armv8.4-a+sme
|
||||
else
|
||||
override CFLAGS += -DBUILD_KERNEL -DTABLE_NAME=gotoblas_$(TARGET_CORE) -march=armv8.4-a+sme
|
||||
override LDFLAGS += -lclang_rt_builtins-aarch64
|
||||
endif
|
||||
ifdef OS_WINDOWS
|
||||
ifeq ($(C_COMPILER), CLANG)
|
||||
override CFLAGS += --aarch64-stack-hazard-size=0
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(TARGET_CORE), SAPPHIRERAPIDS)
|
||||
override CFLAGS += -DBUILD_KERNEL -DTABLE_NAME=gotoblas_$(TARGET_CORE)
|
||||
|
||||
@@ -101,6 +101,16 @@ SBGEMVTKERNEL = ../x86_64/sbgemv_t.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_HFLOAT16),1)
|
||||
ifndef SHGEMVNKERNEL
|
||||
SHGEMVNKERNEL = ../generic/gemv_n.c
|
||||
endif
|
||||
|
||||
ifndef SHGEMVTKERNEL
|
||||
SHGEMVTKERNEL = ../generic/gemv_t.c
|
||||
endif
|
||||
endif
|
||||
|
||||
### GER ###
|
||||
|
||||
ifndef SGERKERNEL
|
||||
@@ -299,6 +309,12 @@ SBBLASOBJS += \
|
||||
sbgemv_t$(TSUFFIX).$(SUFFIX)
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_HFLOAT16),1)
|
||||
SHBLASOBJS += \
|
||||
shgemv_n$(TSUFFIX).$(SUFFIX) \
|
||||
shgemv_t$(TSUFFIX).$(SUFFIX)
|
||||
endif
|
||||
|
||||
ifneq "$(or $(BUILD_SINGLE), $(BUILD_DOUBLE), $(BUILD_COMPLEX))" ""
|
||||
$(KDIR)sgemv_n$(TSUFFIX).$(SUFFIX) $(KDIR)sgemv_n$(TSUFFIX).$(PSUFFIX) : $(KERNELDIR)/$(SGEMVNKERNEL) $(TOPDIR)/common.h $(GEMVDEP)
|
||||
$(CC) -c $(CFLAGS) -UDOUBLE -UCOMPLEX -UTRANS $< -o $@
|
||||
@@ -558,3 +574,10 @@ $(KDIR)bgemv_t$(TSUFFIX).$(SUFFIX) $(KDIR)bgemv_t$(TPSUFFIX).$(PSUFFIX) : $(KERN
|
||||
$(CC) -c $(CFLAGS) -DBGEMM -UCOMPLEX $< -o $@
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_HFLOAT16),1)
|
||||
$(KDIR)shgemv_n$(TSUFFIX).$(SUFFIX) $(KDIR)shgemv_n$(TPSUFFIX).$(PSUFFIX) : $(KERNELDIR)/$(SHGEMVNKERNEL)
|
||||
$(CC) -c $(CFLAGS) -UCOMPLEX $< -o $@
|
||||
$(KDIR)shgemv_t$(TSUFFIX).$(SUFFIX) $(KDIR)shgemv_t$(TPSUFFIX).$(PSUFFIX) : $(KERNELDIR)/$(SHGEMVTKERNEL)
|
||||
$(CC) -c $(CFLAGS) -UCOMPLEX $< -o $@
|
||||
endif
|
||||
|
||||
|
||||
+145
-7
@@ -52,6 +52,18 @@ endif
|
||||
ifeq ($(ARCH), arm64)
|
||||
USE_TRMM = 1
|
||||
USE_DIRECT_SGEMM = 1
|
||||
USE_DIRECT_SSYMM = 1
|
||||
USE_DIRECT_SSYRK = 1
|
||||
USE_DIRECT_SSYR2K = 1
|
||||
USE_DIRECT_STRMM = 1
|
||||
ifeq ($(CORE), ARMV9SME)
|
||||
USE_SME = 1
|
||||
endif
|
||||
ifeq ($(CORE), VORTEXM4)
|
||||
ifneq ($(C_COMPILER), GCC)
|
||||
USE_SME = 1
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH), riscv64)
|
||||
@@ -128,11 +140,44 @@ SGEMMDIRECTKERNEL = sgemm_direct_skylakex.c
|
||||
SGEMMDIRECTPERFORMANT = sgemm_direct_performant.c
|
||||
endif
|
||||
ifeq ($(ARCH), arm64)
|
||||
SGEMMDIRECTKERNEL = sgemm_direct_arm64_sme1.c
|
||||
SGEMMDIRECTKERNEL_ALPHA_BETA = sgemm_direct_alpha_beta_arm64_sme1.c
|
||||
SGEMMDIRECTPERFORMANT = sgemm_direct_performant.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USE_DIRECT_SSYMM
|
||||
ifndef SSYMMDIRECTKERNEL_ALPHA_BETA
|
||||
ifeq ($(ARCH), arm64)
|
||||
SSYMMDIRECTKERNEL_ALPHA_BETA = ssymm_direct_alpha_beta_arm64_sme1.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USE_DIRECT_STRMM
|
||||
ifndef STRMMDIRECTKERNEL
|
||||
ifeq ($(ARCH), arm64)
|
||||
STRMMDIRECTKERNEL = strmm_direct_arm64_sme1.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USE_DIRECT_SSYRK
|
||||
ifndef SSYRKDIRECTKERNEL_ALPHA_BETA
|
||||
ifeq ($(ARCH), arm64)
|
||||
SSYRKDIRECTKERNEL_ALPHA_BETA = ssyrk_direct_alpha_beta_arm64_sme1.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USE_DIRECT_SSYR2K
|
||||
ifndef SSYR2KDIRECTKERNEL_ALPHA_BETA
|
||||
ifeq ($(ARCH), arm64)
|
||||
ifeq ($(TARGET_CORE), ARMV9SME)
|
||||
HAVE_SME = 1
|
||||
endif
|
||||
SGEMMDIRECTKERNEL = sgemm_direct_arm64_sme1.c
|
||||
SGEMMDIRECTKERNEL_ALPHA_BETA = sgemm_direct_alpha_beta_arm64_sme1.c
|
||||
SSYR2KDIRECTKERNEL_ALPHA_BETA = ssyr2k_direct_alpha_beta_arm64_sme1.c
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@@ -209,17 +254,52 @@ SKERNELOBJS += \
|
||||
endif
|
||||
ifeq ($(ARCH), arm64)
|
||||
SKERNELOBJS += \
|
||||
sgemm_direct_performant$(TSUFFIX).$(SUFFIX) \
|
||||
sgemm_direct$(TSUFFIX).$(SUFFIX) \
|
||||
sgemm_direct_alpha_beta$(TSUFFIX).$(SUFFIX)
|
||||
ifdef HAVE_SME
|
||||
ifdef USE_SME
|
||||
SKERNELOBJS += \
|
||||
sgemm_direct_sme1$(TSUFFIX).$(SUFFIX) \
|
||||
sgemm_direct_sme1_2VLx2VL$(TSUFFIX).$(SUFFIX) \
|
||||
sgemm_direct_sme1_preprocess$(TSUFFIX).$(SUFFIX)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USE_DIRECT_SSYMM
|
||||
ifeq ($(ARCH), arm64)
|
||||
SKERNELOBJS += \
|
||||
ssymm_direct_alpha_betaLU$(TSUFFIX).$(SUFFIX) \
|
||||
ssymm_direct_alpha_betaLL$(TSUFFIX).$(SUFFIX)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USE_DIRECT_STRMM
|
||||
ifeq ($(ARCH), arm64)
|
||||
SKERNELOBJS += \
|
||||
strmm_direct_LNUN$(TSUFFIX).$(SUFFIX) strmm_direct_LNLN$(TSUFFIX).$(SUFFIX) \
|
||||
strmm_direct_LTUN$(TSUFFIX).$(SUFFIX) strmm_direct_LTLN$(TSUFFIX).$(SUFFIX)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USE_DIRECT_SSYRK
|
||||
ifeq ($(ARCH), arm64)
|
||||
SKERNELOBJS += \
|
||||
ssyrk_direct_alpha_betaUN$(TSUFFIX).$(SUFFIX) ssyrk_direct_alpha_betaUT$(TSUFFIX).$(SUFFIX) \
|
||||
ssyrk_direct_alpha_betaLN$(TSUFFIX).$(SUFFIX) ssyrk_direct_alpha_betaLT$(TSUFFIX).$(SUFFIX)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USE_DIRECT_SSYR2K
|
||||
ifeq ($(ARCH), arm64)
|
||||
SKERNELOBJS += \
|
||||
ssyr2k_direct_alpha_betaUN$(TSUFFIX).$(SUFFIX) ssyr2k_direct_alpha_betaUN$(TSUFFIX).$(SUFFIX) \
|
||||
ssyr2k_direct_alpha_betaUT$(TSUFFIX).$(SUFFIX) ssyr2k_direct_alpha_betaUT$(TSUFFIX).$(SUFFIX) \
|
||||
ssyr2k_direct_alpha_betaLN$(TSUFFIX).$(SUFFIX) ssyr2k_direct_alpha_betaLN$(TSUFFIX).$(SUFFIX) \
|
||||
ssyr2k_direct_alpha_betaLT$(TSUFFIX).$(SUFFIX) ssyr2k_direct_alpha_betaLT$(TSUFFIX).$(SUFFIX)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq "$(or $(BUILD_DOUBLE),$(BUILD_COMPLEX16))" ""
|
||||
DKERNELOBJS += \
|
||||
dgemm_beta$(TSUFFIX).$(SUFFIX) \
|
||||
@@ -969,19 +1049,46 @@ $(KDIR)sgemm_direct$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(SGEMMDIRECTKERNEL)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX $< -o $@
|
||||
endif
|
||||
ifeq ($(ARCH), arm64)
|
||||
$(KDIR)sgemm_direct_performant$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(SGEMMDIRECTPERFORMANT)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX $< -o $@
|
||||
$(KDIR)sgemm_direct$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(SGEMMDIRECTKERNEL)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX $< -o $@
|
||||
$(KDIR)sgemm_direct_alpha_beta$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(SGEMMDIRECTKERNEL_ALPHA_BETA)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX $< -o $@
|
||||
ifdef HAVE_SME
|
||||
$(KDIR)sgemm_direct_sme1$(TSUFFIX).$(SUFFIX) :
|
||||
$(CC) $(CFLAGS) -c $(KERNELDIR)/sgemm_direct_sme1.S -UDOUBLE -UCOMPLEX -o $@
|
||||
ifdef USE_SME
|
||||
$(KDIR)sgemm_direct_sme1_2VLx2VL$(TSUFFIX).$(SUFFIX) :
|
||||
$(CC) $(CFLAGS) -c $(KERNELDIR)/sgemm_direct_sme1_2VLx2VL.S -UDOUBLE -UCOMPLEX -o $@
|
||||
$(KDIR)sgemm_direct_sme1_preprocess$(TSUFFIX).$(SUFFIX) :
|
||||
$(CC) $(CFLAGS) -c $(KERNELDIR)/sgemm_direct_sme1_preprocess.S -UDOUBLE -UCOMPLEX -o $@
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USE_DIRECT_SSYMM
|
||||
ifeq ($(ARCH), arm64)
|
||||
$(KDIR)ssymm_direct_alpha_betaLU$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(SSYMMDIRECTKERNEL_ALPHA_BETA)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX -DLEFT -DUPPER $< -o $@
|
||||
$(KDIR)ssymm_direct_alpha_betaLL$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(SSYMMDIRECTKERNEL_ALPHA_BETA)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX -DLEFT -DLOWER $< -o $@
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USE_DIRECT_SSYRK
|
||||
ifeq ($(ARCH), arm64)
|
||||
$(KDIR)ssyrk_direct_alpha_betaUN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(SSYRKDIRECTKERNEL_ALPHA_BETA)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX -DUPPER -UTRANSA $< -o $@
|
||||
|
||||
$(KDIR)ssyrk_direct_alpha_betaUT$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(SSYRKDIRECTKERNEL_ALPHA_BETA)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX -DUPPER -DTRANSA $< -o $@
|
||||
|
||||
$(KDIR)ssyrk_direct_alpha_betaLN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(SSYRKDIRECTKERNEL_ALPHA_BETA)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX -UUPPER -UTRANSA $< -o $@
|
||||
|
||||
$(KDIR)ssyrk_direct_alpha_betaLT$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(SSYRKDIRECTKERNEL_ALPHA_BETA)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX -UUPPER -DTRANSA $< -o $@
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_BFLOAT16), 1)
|
||||
$(KDIR)bgemm_kernel$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(BGEMMKERNEL)
|
||||
$(CC) $(CFLAGS) -c -DBFLOAT16 -DBGEMM -UDOUBLE -UCOMPLEX $< -o $@
|
||||
@@ -1109,6 +1216,20 @@ $(KDIR)xgemm_kernel_b$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(XGEMMKERNEL) $(XGEMMD
|
||||
$(CC) $(CFLAGS) -c -DXDOUBLE -DCOMPLEX -DCC $< -o $@
|
||||
|
||||
|
||||
ifdef USE_DIRECT_SSYR2K
|
||||
ifeq ($(ARCH), arm64)
|
||||
$(KDIR)ssyr2k_direct_alpha_betaUN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(SSYR2KDIRECTKERNEL_ALPHA_BETA)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX -DUPPER -UTRANSA $< -o $@
|
||||
$(KDIR)ssyr2k_direct_alpha_betaUT$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(SSYR2KDIRECTKERNEL_ALPHA_BETA)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX -DUPPER -DTRANSA $< -o $@
|
||||
$(KDIR)ssyr2k_direct_alpha_betaLN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(SSYR2KDIRECTKERNEL_ALPHA_BETA)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX -UUPPER -UTRANSA $< -o $@
|
||||
$(KDIR)ssyr2k_direct_alpha_betaLT$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(SSYR2KDIRECTKERNEL_ALPHA_BETA)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX -UUPPER -DTRANSA $< -o $@
|
||||
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef USE_TRMM
|
||||
$(KDIR)strmm_kernel_LN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(STRMMKERNEL)
|
||||
ifeq ($(OS), AIX)
|
||||
@@ -1150,6 +1271,23 @@ else
|
||||
$(CC) $(CFLAGS) -c -DTRMMKERNEL -UDOUBLE -UCOMPLEX -ULEFT -DTRANSA $< -o $@
|
||||
endif
|
||||
|
||||
|
||||
ifdef USE_DIRECT_STRMM
|
||||
ifeq ($(ARCH), arm64)
|
||||
$(KDIR)strmm_direct_LNUN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(STRMMDIRECTKERNEL)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX -UTRANSA -DUPPER $< -o $@
|
||||
|
||||
$(KDIR)strmm_direct_LNLN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(STRMMDIRECTKERNEL)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX -UTRANSA -UUPPER $< -o $@
|
||||
|
||||
$(KDIR)strmm_direct_LTUN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(STRMMDIRECTKERNEL)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX -DTRANSA -DUPPER $< -o $@
|
||||
|
||||
$(KDIR)strmm_direct_LTLN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(STRMMDIRECTKERNEL)
|
||||
$(CC) $(CFLAGS) -c -UDOUBLE -UCOMPLEX -DTRANSA -UUPPER $< -o $@
|
||||
endif
|
||||
endif
|
||||
|
||||
$(KDIR)dtrmm_kernel_LN$(TSUFFIX).$(SUFFIX) : $(KERNELDIR)/$(DTRMMKERNEL)
|
||||
ifeq ($(OS), AIX)
|
||||
$(CC) $(CFLAGS) -S -DTRMMKERNEL -DDOUBLE -UCOMPLEX -DLEFT -UTRANSA $< -o - > dtrmm_kernel_ln.s
|
||||
|
||||
@@ -5,8 +5,11 @@ DGEMVNKERNEL = gemv_n_sve_v4x3.c
|
||||
SGEMVTKERNEL = gemv_t_sve_v4x3.c
|
||||
DGEMVTKERNEL = gemv_t_sve_v4x3.c
|
||||
|
||||
DDOTKERNEL = dot_sve_v8.c
|
||||
SDOTKERNEL = dot_sve_v8.c
|
||||
DDOTKERNEL = dot.c
|
||||
SDOTKERNEL = dot.c
|
||||
|
||||
SAXPYKERNEL = axpy_sve.c
|
||||
DAXPYKERNEL = axpy_sve.c
|
||||
|
||||
SGERKERNEL = ger_sve_v1x3.c
|
||||
DGERKERNEL = ger_sve_v1x3.c
|
||||
|
||||
@@ -102,18 +102,8 @@ ZNRM2KERNEL = znrm2.S
|
||||
|
||||
DDOTKERNEL = dot.c
|
||||
SDOTKERNEL = dot.c
|
||||
ifeq ($(OSNAME), WINNT)
|
||||
ifeq ($(C_COMPILER), CLANG)
|
||||
CDOTKERNEL = zdot.S
|
||||
ZDOTKERNEL = zdot.S
|
||||
else
|
||||
CDOTKERNEL = zdot_thunderx2t99.c
|
||||
ZDOTKERNEL = zdot_thunderx2t99.c
|
||||
endif
|
||||
else
|
||||
CDOTKERNEL = zdot_thunderx2t99.c
|
||||
ZDOTKERNEL = zdot_thunderx2t99.c
|
||||
endif
|
||||
DSDOTKERNEL = dot.S
|
||||
|
||||
DGEMM_BETA = dgemm_beta.S
|
||||
|
||||
@@ -189,7 +189,7 @@ ZGEMMONCOPYOBJ = zgemm_oncopy$(TSUFFIX).$(SUFFIX)
|
||||
ZGEMMOTCOPYOBJ = zgemm_otcopy$(TSUFFIX).$(SUFFIX)
|
||||
|
||||
ifeq ($(BUILD_BFLOAT16), 1)
|
||||
BGEMM_BETA = sbgemm_beta_neoversen2.c
|
||||
BGEMM_BETA = bgemm_beta_neon.c
|
||||
BGEMMKERNEL = sbgemm_kernel_$(BGEMM_UNROLL_M)x$(BGEMM_UNROLL_N)_neoversen2.c
|
||||
BGEMMINCOPY = sbgemm_ncopy_$(BGEMM_UNROLL_M)_neoversen2.c
|
||||
BGEMMITCOPY = sbgemm_tcopy_$(BGEMM_UNROLL_M)_neoversen2.c
|
||||
|
||||
@@ -70,3 +70,6 @@ SBGEMVNKERNEL = sbgemv_n_neon.c
|
||||
SBGEMVTKERNEL = sbgemv_t_bfdot.c
|
||||
|
||||
endif
|
||||
|
||||
SGERKERNEL = ger_sve_v1x3.c
|
||||
DGERKERNEL = ger_sve_v1x3.c
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
include $(KERNELDIR)/KERNEL.NEOVERSEN1
|
||||
@@ -40,7 +40,8 @@
|
||||
|
||||
#define UPDATE_C(PG, PTR, DST, SRC) \
|
||||
do { \
|
||||
DST = svreinterpret_f32_u32(svld1uh_u32((pghalf), (uint16_t*)PTR)); \
|
||||
svtmp16 = svld1_bf16((pghalf), (PTR)); \
|
||||
DST = svreinterpret_f32(svzip1_bf16(zeros, svtmp16)); \
|
||||
DST = svadd_z((PG), SRC, DST); \
|
||||
svtmp16 = svcvt_bf16_f32_z((PG), DST); \
|
||||
svtmp16 = svuzp1_bf16(svtmp16, svtmp16); \
|
||||
@@ -55,7 +56,8 @@
|
||||
|
||||
#define UPDATE_C(PG, PTR, DST, SRC) \
|
||||
do { \
|
||||
DST = svreinterpret_f32_u32(svld1uh_u32((pghalf), (uint16_t*)PTR)); \
|
||||
svtmp16 = svld1_bf16((pghalf), (PTR)); \
|
||||
DST = svreinterpret_f32(svzip1_bf16(zeros, svtmp16)); \
|
||||
DST = svmad_z((PG), svalpha, SRC, DST); \
|
||||
svtmp16 = svcvt_bf16_f32_z((PG), DST); \
|
||||
svtmp16 = svuzp1_bf16(svtmp16, svtmp16); \
|
||||
@@ -133,6 +135,7 @@ static int bgemm_kernel_neoversev1_alpha(BLASLONG m, BLASLONG n, BLASLONG k,
|
||||
OUTPUT_FLOAT *ptr_c0, *ptr_c1, *ptr_c2, *ptr_c3;
|
||||
svfloat32_t tmp0, tmp1, tmp2, tmp3;
|
||||
#ifdef BGEMM
|
||||
svbfloat16_t zeros = svdup_n_bf16(TO16(0.0));
|
||||
svbfloat16_t svtmp16;
|
||||
#else
|
||||
float32x2_t tmp4, tmp5, tmp6, tmp7;
|
||||
|
||||
+35
-4
@@ -42,6 +42,8 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifdef USE_SVE
|
||||
#ifdef DOT_KERNEL_SVE
|
||||
#include DOT_KERNEL_SVE
|
||||
#elif defined(A64FX)
|
||||
#include "dot_kernel_sve_v8.c"
|
||||
#else
|
||||
#include "dot_kernel_sve.c"
|
||||
#endif
|
||||
@@ -82,14 +84,43 @@ static inline int get_dot_optimal_nthreads_neoversev1(BLASLONG N, int ncpu) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DYNAMIC_ARCH) || defined(A64FX)
|
||||
static inline int get_dot_optimal_nthreads_a64fx(BLASLONG N, int ncpu) {
|
||||
#ifdef DOUBLE
|
||||
return (N <= 11000L) ? 1
|
||||
: (N <= 20000L) ? MIN(ncpu, 2)
|
||||
: (N <= 35000L) ? MIN(ncpu, 4)
|
||||
: (N <= 50000L) ? MIN(ncpu, 6)
|
||||
: (N <= 440000L) ? MIN(ncpu, 8)
|
||||
: (N <= 880000L) ? MIN(ncpu, 16)
|
||||
: (N <= 1020000L) ? MIN(ncpu, 24)
|
||||
: ncpu;
|
||||
#else
|
||||
return (N <= 22000L) ? 1
|
||||
: (N <= 39000L) ? MIN(ncpu, 2)
|
||||
: (N <= 79000L) ? MIN(ncpu, 4)
|
||||
: (N <= 120000L) ? MIN(ncpu, 6)
|
||||
: (N <= 1020000L) ? MIN(ncpu, 8)
|
||||
: ncpu;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int get_dot_optimal_nthreads(BLASLONG n) {
|
||||
int ncpu = num_cpu_avail(1);
|
||||
|
||||
#if defined(NEOVERSEV1) && !defined(COMPLEX) && !defined(BFLOAT16)
|
||||
#if defined(A64FX) && !defined(COMPLEX) && !defined(BFLOAT16)
|
||||
return get_dot_optimal_nthreads_a64fx(n, ncpu);
|
||||
#elif defined(NEOVERSEV1) && !defined(COMPLEX) && !defined(BFLOAT16)
|
||||
return get_dot_optimal_nthreads_neoversev1(n, ncpu);
|
||||
#elif defined(DYNAMIC_ARCH) && !defined(COMPLEX) && !defined(BFLOAT16)
|
||||
if (strcmp(gotoblas_corename(), "neoversev1") == 0) {
|
||||
return get_dot_optimal_nthreads_neoversev1(n, ncpu);
|
||||
{
|
||||
const char *core = gotoblas_corename();
|
||||
if (strcmp(core, "a64fx") == 0) {
|
||||
return get_dot_optimal_nthreads_a64fx(n, ncpu);
|
||||
} else if (strcmp(core, "neoversev1") == 0) {
|
||||
return get_dot_optimal_nthreads_neoversev1(n, ncpu);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -97,7 +128,7 @@ static inline int get_dot_optimal_nthreads(BLASLONG n) {
|
||||
if (n <= 10000L)
|
||||
return 1;
|
||||
else
|
||||
return num_cpu_avail(1);
|
||||
return ncpu;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
" add x12, %[X_], x9, lsl #"SHIFT" \n" \
|
||||
" add x13, %[Y_], x9, lsl #"SHIFT" \n"
|
||||
#define TAIL_WHILE \
|
||||
" whilelo p1."DTYPE", x8, x0 \n"
|
||||
" whilelo p1."DTYPE", x8, %[N_] \n"
|
||||
#define UPDATE(pg, x,y,out) \
|
||||
" ld1"WIDTH" { z2."DTYPE" }, "pg"/z, ["x", x8, lsl #"SHIFT"] \n" \
|
||||
" ld1"WIDTH" { z3."DTYPE" }, "pg"/z, ["y", x8, lsl #"SHIFT"] \n" \
|
||||
@@ -66,7 +66,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
" movi d1, #0x0 \n" \
|
||||
SETUP_TRUE \
|
||||
" neg x10, x9, lsl #1 \n" \
|
||||
" ands x11, x10, x0 \n" \
|
||||
" ands x11, x10, %[N_] \n" \
|
||||
" b.eq 2f // skip_2x \n" \
|
||||
OFFSET_INPUTS \
|
||||
"1: // vector_2x \n" \
|
||||
@@ -78,7 +78,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
SUM_VECTOR("1") \
|
||||
"2: // skip_2x \n" \
|
||||
" neg x10, x9 \n" \
|
||||
" and x10, x10, x0 \n" \
|
||||
" and x10, x10, %[N_] \n" \
|
||||
" cmp x8, x10 \n" \
|
||||
" b.hs 4f // tail \n" \
|
||||
"3: // vector_1x \n" \
|
||||
@@ -87,7 +87,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
" cmp x8, x10 \n" \
|
||||
" b.lo 3b // vector_1x \n" \
|
||||
"4: // tail \n" \
|
||||
" cmp x10, x0 \n" \
|
||||
" cmp x10, %[N_] \n" \
|
||||
" b.eq 5f // end \n" \
|
||||
TAIL_WHILE \
|
||||
UPDATE("p1", "%[X_]", "%[Y_]", "z0") \
|
||||
@@ -110,9 +110,9 @@ dot_kernel_sve(BLASLONG n, FLOAT* x, FLOAT* y)
|
||||
[Y_] "r" (y)
|
||||
: "cc",
|
||||
"memory",
|
||||
"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
|
||||
"x8", "x9", "x10", "x11", "x12", "x13", "d1",
|
||||
"z0", "z1"
|
||||
"x8", "x9", "x10", "x11", "x12", "x13",
|
||||
"v0", "v1",
|
||||
"z0", "z1", "z2", "z3"
|
||||
);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/***************************************************************************
|
||||
Copyright (c) 2025, The OpenBLAS Project
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
3. Neither the name of the OpenBLAS project nor the names of
|
||||
its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBLAS PROJECT OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <arm_sve.h>
|
||||
#include "common.h"
|
||||
|
||||
#ifdef DOUBLE
|
||||
#define SV_COUNT svcntd
|
||||
#define SV_TYPE svfloat64_t
|
||||
#define SV_TRUE svptrue_b64
|
||||
#define SV_WHILE svwhilelt_b64_s64
|
||||
#define SV_DUP svdup_f64
|
||||
#else
|
||||
#define SV_COUNT svcntw
|
||||
#define SV_TYPE svfloat32_t
|
||||
#define SV_TRUE svptrue_b32
|
||||
#define SV_WHILE svwhilelt_b32_s64
|
||||
#define SV_DUP svdup_f32
|
||||
#endif
|
||||
|
||||
int CNAME(BLASLONG m, BLASLONG n, BLASLONG dummy1, FLOAT alpha,
|
||||
FLOAT *x, BLASLONG incx,
|
||||
FLOAT *y, BLASLONG incy,
|
||||
FLOAT *a, BLASLONG lda, FLOAT *buffer){
|
||||
|
||||
FLOAT *X = x;
|
||||
|
||||
if (incx != 1) {
|
||||
X = buffer;
|
||||
COPY_K(m, x, incx, X, 1);
|
||||
}
|
||||
|
||||
BLASLONG width = (n + 3 - 1) / 3;
|
||||
BLASLONG i, j;
|
||||
BLASLONG sve_size = SV_COUNT();
|
||||
|
||||
FLOAT *y0_ptr = y + incy * width * 0;
|
||||
FLOAT *y1_ptr = y + incy * width * 1;
|
||||
FLOAT *y2_ptr = y + incy * width * 2;
|
||||
|
||||
for (j = 0; j < width; j++) {
|
||||
svbool_t pg00 = (j + width * 0 < n) ? SV_TRUE() : svpfalse();
|
||||
svbool_t pg01 = (j + width * 1 < n) ? SV_TRUE() : svpfalse();
|
||||
svbool_t pg02 = (j + width * 2 < n) ? SV_TRUE() : svpfalse();
|
||||
|
||||
SV_TYPE temp0_vec = (j + width * 0 < n) ? SV_DUP(alpha * *y0_ptr) : SV_DUP(0.0);
|
||||
SV_TYPE temp1_vec = (j + width * 1 < n) ? SV_DUP(alpha * *y1_ptr) : SV_DUP(0.0);
|
||||
SV_TYPE temp2_vec = (j + width * 2 < n) ? SV_DUP(alpha * *y2_ptr) : SV_DUP(0.0);
|
||||
|
||||
FLOAT *x_ptr = X;
|
||||
FLOAT *a0_ptr = a + lda * width * 0 + lda * j;
|
||||
FLOAT *a1_ptr = a + lda * width * 1 + lda * j;
|
||||
FLOAT *a2_ptr = a + lda * width * 2 + lda * j;
|
||||
|
||||
i = 0;
|
||||
while (i + sve_size * 1 - 1 < m) {
|
||||
SV_TYPE x0_vec = svld1_vnum(SV_TRUE(), x_ptr, 0);
|
||||
|
||||
SV_TYPE a00_vec = svld1_vnum(pg00, a0_ptr, 0);
|
||||
SV_TYPE a01_vec = svld1_vnum(pg01, a1_ptr, 0);
|
||||
SV_TYPE a02_vec = svld1_vnum(pg02, a2_ptr, 0);
|
||||
|
||||
a00_vec = svmla_x(pg00, a00_vec, temp0_vec, x0_vec);
|
||||
a01_vec = svmla_x(pg01, a01_vec, temp1_vec, x0_vec);
|
||||
a02_vec = svmla_x(pg02, a02_vec, temp2_vec, x0_vec);
|
||||
|
||||
svst1_vnum(pg00, a0_ptr, 0, a00_vec);
|
||||
svst1_vnum(pg01, a1_ptr, 0, a01_vec);
|
||||
svst1_vnum(pg02, a2_ptr, 0, a02_vec);
|
||||
|
||||
i += sve_size * 1;
|
||||
x_ptr += sve_size * 1;
|
||||
a0_ptr += sve_size * 1;
|
||||
a1_ptr += sve_size * 1;
|
||||
a2_ptr += sve_size * 1;
|
||||
}
|
||||
|
||||
if (i < m) {
|
||||
svbool_t pg0 = SV_WHILE(i + sve_size * 0, m);
|
||||
|
||||
pg00 = svand_z(SV_TRUE(), pg0, pg00);
|
||||
pg01 = svand_z(SV_TRUE(), pg0, pg01);
|
||||
pg02 = svand_z(SV_TRUE(), pg0, pg02);
|
||||
|
||||
SV_TYPE x0_vec = svld1_vnum(pg0, x_ptr, 0);
|
||||
|
||||
SV_TYPE a00_vec = svld1_vnum(pg00, a0_ptr, 0);
|
||||
SV_TYPE a01_vec = svld1_vnum(pg01, a1_ptr, 0);
|
||||
SV_TYPE a02_vec = svld1_vnum(pg02, a2_ptr, 0);
|
||||
|
||||
a00_vec = svmla_x(pg00, a00_vec, temp0_vec, x0_vec);
|
||||
a01_vec = svmla_x(pg01, a01_vec, temp1_vec, x0_vec);
|
||||
a02_vec = svmla_x(pg02, a02_vec, temp2_vec, x0_vec);
|
||||
|
||||
svst1_vnum(pg00, a0_ptr, 0, a00_vec);
|
||||
svst1_vnum(pg01, a1_ptr, 0, a01_vec);
|
||||
svst1_vnum(pg02, a2_ptr, 0, a02_vec);
|
||||
}
|
||||
|
||||
y0_ptr += incy;
|
||||
y1_ptr += incy;
|
||||
y2_ptr += incy;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
+10
-37
@@ -35,16 +35,13 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#define I x3
|
||||
|
||||
#if !defined(DOUBLE)
|
||||
#define SSQ s0
|
||||
#define SCALE s1
|
||||
#define REGZERO s5
|
||||
#define REGONE s6
|
||||
#else
|
||||
#define SSQF s0
|
||||
#endif
|
||||
|
||||
#define SSQ d0
|
||||
#define SCALE d1
|
||||
#define REGZERO d5
|
||||
#define REGONE d6
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Macro definitions
|
||||
@@ -53,22 +50,10 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.macro KERNEL_F1
|
||||
#if !defined(DOUBLE)
|
||||
ldr s4, [X], #4
|
||||
fcmp s4, REGZERO
|
||||
beq 2f /* KERNEL_F1_NEXT_\@ */
|
||||
fabs s4, s4
|
||||
fcmp SCALE, s4
|
||||
bge 1f /* KERNEL_F1_SCALE_GE_X_\@ */
|
||||
fdiv s2, SCALE, s4
|
||||
fmul s2, s2, s2
|
||||
fmul s3, SSQ, s2
|
||||
fadd SSQ, REGONE, s3
|
||||
fmov SCALE, s4
|
||||
b 2f /* KERNEL_F1_NEXT_\@ */
|
||||
1: /* KERNEL_F1_SCALE_GE_X_\@: */
|
||||
fdiv s2, s4, SCALE
|
||||
fmla SSQ, s2, v2.s[0]
|
||||
fcvt d4, s4
|
||||
#else
|
||||
ldr d4, [X], #8
|
||||
#endif
|
||||
fcmp d4, REGZERO
|
||||
beq 2f /* KERNEL_F1_NEXT_\@ */
|
||||
fabs d4, d4
|
||||
@@ -83,29 +68,16 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
1: /* KERNEL_F1_SCALE_GE_X_\@: */
|
||||
fdiv d2, d4, SCALE
|
||||
fmla SSQ, d2, v2.d[0]
|
||||
#endif
|
||||
2: /* KERNEL_F1_NEXT_\@: */
|
||||
.endm
|
||||
|
||||
.macro KERNEL_S1
|
||||
#if !defined(DOUBLE)
|
||||
ldr s4, [X]
|
||||
fcmp s4, REGZERO
|
||||
beq KERNEL_S1_NEXT
|
||||
fabs s4, s4
|
||||
fcmp SCALE, s4
|
||||
bge KERNEL_S1_SCALE_GE_X
|
||||
fdiv s2, SCALE, s4
|
||||
fmul s2, s2, s2
|
||||
fmul s3, SSQ, s2
|
||||
fadd SSQ, REGONE, s3
|
||||
fmov SCALE, s4
|
||||
b KERNEL_S1_NEXT
|
||||
KERNEL_S1_SCALE_GE_X:
|
||||
fdiv s2, s4, SCALE
|
||||
fmla SSQ, s2, v2.s[0]
|
||||
fcvt d4, s4
|
||||
#else
|
||||
ldr d4, [X]
|
||||
#endif
|
||||
fcmp d4, REGZERO
|
||||
beq KERNEL_S1_NEXT
|
||||
fabs d4, d4
|
||||
@@ -120,7 +92,6 @@ KERNEL_S1_SCALE_GE_X:
|
||||
KERNEL_S1_SCALE_GE_X:
|
||||
fdiv d2, d4, SCALE
|
||||
fmla SSQ, d2, v2.d[0]
|
||||
#endif
|
||||
KERNEL_S1_NEXT:
|
||||
add X, X, INC_X
|
||||
.endm
|
||||
@@ -218,7 +189,9 @@ KERNEL_S1_NEXT:
|
||||
.Lnrm2_kernel_L999:
|
||||
fsqrt SSQ, SSQ
|
||||
fmul SSQ, SCALE, SSQ
|
||||
|
||||
#if !defined(DOUBLE)
|
||||
fcvt SSQF, SSQ
|
||||
#endif
|
||||
ret
|
||||
|
||||
EPILOGUE
|
||||
|
||||
@@ -51,7 +51,8 @@
|
||||
#ifdef ALPHA_ONE
|
||||
#define UPDATE_C(PG16, PG32, PTR, SRC) \
|
||||
do { \
|
||||
tmp32 = svreinterpret_f32_u32(svld1uh_u32((PG16), (uint16_t*)PTR)); \
|
||||
tmp16 = svld1_bf16((PG16), (PTR)); \
|
||||
tmp32 = svreinterpret_f32(svzip1_bf16(zeros, tmp16)); \
|
||||
tmp32 = svadd_z((PG32), SRC, tmp32); \
|
||||
tmp16 = svcvt_bf16_f32_z((PG32), tmp32); \
|
||||
tmp16 = svuzp1_bf16(tmp16, tmp16); \
|
||||
@@ -60,7 +61,8 @@
|
||||
#else
|
||||
#define UPDATE_C(PG16, PG32, PTR, SRC) \
|
||||
do { \
|
||||
tmp32 = svreinterpret_f32_u32(svld1uh_u32((PG16), (uint16_t*)PTR)); \
|
||||
tmp16 = svld1_bf16((PG16), (PTR)); \
|
||||
tmp32 = svreinterpret_f32(svzip1_bf16(zeros, tmp16)); \
|
||||
tmp32 = svmad_z((PG32), svalpha, SRC, tmp32); \
|
||||
tmp16 = svcvt_bf16_f32_z((PG32), tmp32); \
|
||||
tmp16 = svuzp1_bf16(tmp16, tmp16); \
|
||||
@@ -121,6 +123,7 @@ static int gemm_kernel_neoversen2_alpha(BLASLONG m, BLASLONG n, BLASLONG k, FLOA
|
||||
#ifdef BGEMM
|
||||
svbool_t pg16_first_2 = svdupq_b16(1, 1, 0, 0, 0, 0, 0, 0);
|
||||
svbool_t pg16_first_1 = svdupq_b16(1, 0, 0, 0, 0, 0, 0, 0);
|
||||
svbfloat16_t zeros = svdup_n_bf16(vcvth_bf16_f32(0.0));
|
||||
#endif
|
||||
|
||||
bfloat16_t *ptr_a = (bfloat16_t *)A;
|
||||
|
||||
@@ -8,16 +8,29 @@
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include "sme_abi.h"
|
||||
|
||||
#if defined(DYNAMIC_ARCH)
|
||||
#define COMBINE(a,b) a ## b
|
||||
#define COMBINE2(a,b) COMBINE(a,b)
|
||||
#define SME1_PREPROCESS_BASE sgemm_direct_sme1_preprocess
|
||||
#define SME1_PREPROCESS COMBINE2(SME1_PREPROCESS_BASE,TS)
|
||||
#define SME1_KERNEL2X2_BASE sgemm_direct_alpha_beta_sme1_2VLx2VL
|
||||
#define SME1_KERNEL2X2 COMBINE2(SME1_KERNEL2X2_BASE,TS)
|
||||
#else
|
||||
#define SME1_PREPROCESS sgemm_direct_sme1_preprocess
|
||||
#define SME1_KERNEL2X2 sgemm_direct_alpha_beta_sme1_2VLx2VL
|
||||
#endif
|
||||
|
||||
/* Function prototypes */
|
||||
extern void SME1_PREPROCESS(uint64_t nbr, uint64_t nbc,\
|
||||
const float * restrict a, float * a_mod);
|
||||
|
||||
#if defined(HAVE_SME)
|
||||
|
||||
#if defined(__ARM_FEATURE_SME) && defined(__clang__) && __clang_major__ >= 16
|
||||
#include <arm_sme.h>
|
||||
#endif
|
||||
|
||||
/* Function prototypes */
|
||||
extern void sgemm_direct_sme1_preprocess(uint64_t nbr, uint64_t nbc,\
|
||||
const float * restrict a, float * a_mod) __asm__("sgemm_direct_sme1_preprocess");
|
||||
|
||||
/* Function Definitions */
|
||||
static uint64_t sve_cntw() {
|
||||
uint64_t cnt;
|
||||
@@ -99,10 +112,11 @@ kernel_2x2(const float *A, const float *B, float *C, size_t shared_dim,
|
||||
svst1_hor_za32(/*tile*/2, /*slice*/i, pg_c_0, &C[i * ldc]);
|
||||
svst1_hor_za32(/*tile*/3, /*slice*/i, pg_c_1, &C[i * ldc + svl]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
__arm_new("za") __arm_locally_streaming
|
||||
void sgemm_direct_alpha_beta_sme1_2VLx2VL(uint64_t m, uint64_t k, uint64_t n, const float* alpha,\
|
||||
void SME1_KERNEL2X2(uint64_t m, uint64_t k, uint64_t n, const float* alpha,\
|
||||
const float *ba, const float *restrict bb, const float* beta,\
|
||||
float *restrict C) {
|
||||
|
||||
@@ -125,6 +139,7 @@ void sgemm_direct_alpha_beta_sme1_2VLx2VL(uint64_t m, uint64_t k, uint64_t n, co
|
||||
// Block over row dimension of C
|
||||
for (; row_idx < num_rows; row_idx += row_batch) {
|
||||
row_batch = MIN(row_batch, num_rows - row_idx);
|
||||
|
||||
uint64_t col_idx = 0;
|
||||
uint64_t col_batch = 2*svl;
|
||||
|
||||
@@ -141,9 +156,9 @@ void sgemm_direct_alpha_beta_sme1_2VLx2VL(uint64_t m, uint64_t k, uint64_t n, co
|
||||
}
|
||||
|
||||
#else
|
||||
void sgemm_direct_alpha_beta_sme1_2VLx2VL(uint64_t m, uint64_t k, uint64_t n, const float* alpha,\
|
||||
void SME1_KERNEL2X2(uint64_t m, uint64_t k, uint64_t n, const float* alpha,\
|
||||
const float *ba, const float *restrict bb, const float* beta,\
|
||||
float *restrict C){}
|
||||
float *restrict C){fprintf(stderr,"empty sgemm_alpha_beta2x2 should never get called!!!\n");}
|
||||
#endif
|
||||
|
||||
/*void sgemm_kernel_direct (BLASLONG M, BLASLONG N, BLASLONG K,\
|
||||
@@ -166,7 +181,7 @@ void CNAME (BLASLONG M, BLASLONG N, BLASLONG K, float alpha, float * __restrict
|
||||
* of reading directly from vector (z) registers.
|
||||
* */
|
||||
asm volatile("" : : :"p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7",
|
||||
"p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",
|
||||
"p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
|
||||
"z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7",
|
||||
"z8", "z9", "z10", "z11", "z12", "z13", "z14", "z15",
|
||||
"z16", "z17", "z18", "z19", "z20", "z21", "z22", "z23",
|
||||
@@ -175,17 +190,19 @@ void CNAME (BLASLONG M, BLASLONG N, BLASLONG K, float alpha, float * __restrict
|
||||
/* Pre-process the left matrix to make it suitable for
|
||||
matrix sum of outer-product calculation
|
||||
*/
|
||||
sgemm_direct_sme1_preprocess(M, K, A, A_mod);
|
||||
|
||||
SME1_PREPROCESS(M, K, A, A_mod);
|
||||
|
||||
asm volatile("" : : :"p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7",
|
||||
"p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",
|
||||
"p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15","d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
|
||||
"z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7",
|
||||
"z8", "z9", "z10", "z11", "z12", "z13", "z14", "z15",
|
||||
"z16", "z17", "z18", "z19", "z20", "z21", "z22", "z23",
|
||||
"z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31");
|
||||
|
||||
/* Calculate C = alpha*A*B + beta*C */
|
||||
sgemm_direct_alpha_beta_sme1_2VLx2VL(M, K, N, &alpha, A_mod, B, &beta, R);
|
||||
|
||||
SME1_KERNEL2X2(M, K, N, &alpha, A_mod, B, &beta, R);
|
||||
|
||||
free(A_mod);
|
||||
}
|
||||
@@ -194,6 +211,6 @@ void CNAME (BLASLONG M, BLASLONG N, BLASLONG K, float alpha, float * __restrict
|
||||
|
||||
void CNAME (BLASLONG M, BLASLONG N, BLASLONG K, float alpha, float * __restrict A,\
|
||||
BLASLONG strideA, float * __restrict B, BLASLONG strideB ,\
|
||||
float beta, float * __restrict R, BLASLONG strideR){}
|
||||
|
||||
float beta, float * __restrict R, BLASLONG strideR){fprintf(stderr,"empty sgemm_direct_alpha_beta should not be called!!!\n");}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -7,18 +7,29 @@
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#if defined(DYNAMIC_ARCH)
|
||||
#define COMBINE(a,b) a ## b
|
||||
#define COMBINE2(a,b) COMBINE(a,b)
|
||||
#define SME1_PREPROCESS_BASE sgemm_direct_sme1_preprocess
|
||||
#define SME1_PREPROCESS COMBINE2(SME1_PREPROCESS_BASE,TS)
|
||||
#define SME1_DIRECT2X2_BASE sgemm_direct_sme1_2VLx2VL
|
||||
#define SME1_DIRECT2X2 COMBINE2(SME1_DIRECT2X2_BASE,TS)
|
||||
#else
|
||||
#define SME1_PREPROCESS sgemm_direct_sme1_preprocess
|
||||
#define SME1_DIRECT2X2 sgemm_direct_sme1_2VLx2VL
|
||||
#endif
|
||||
#if defined(HAVE_SME)
|
||||
|
||||
/* Function prototypes */
|
||||
extern void sgemm_direct_sme1_preprocess(uint64_t nbr, uint64_t nbc,\
|
||||
const float * restrict a, float * a_mod) __asm__("sgemm_direct_sme1_preprocess");
|
||||
extern void sgemm_direct_sme1_2VLx2VL(uint64_t m, uint64_t k, uint64_t n,\
|
||||
extern void SME1_PREPROCESS(uint64_t nbr, uint64_t nbc,\
|
||||
const float * restrict a, float * a_mod) ;
|
||||
|
||||
extern void SME1_DIRECT2X2(uint64_t m, uint64_t k, uint64_t n,\
|
||||
const float * matLeft,\
|
||||
const float * restrict matRight,\
|
||||
const float * restrict matResult) __asm__("sgemm_direct_sme1_2VLx2VL");
|
||||
const float * restrict matResult) ;
|
||||
|
||||
/* Function Definitions */
|
||||
uint64_t sve_cntw() {
|
||||
static uint64_t sve_cntw() {
|
||||
uint64_t cnt;
|
||||
asm volatile(
|
||||
"rdsvl %[res], #1\n"
|
||||
@@ -39,7 +50,6 @@ void CNAME (BLASLONG M, BLASLONG N, BLASLONG K, float * __restrict A,\
|
||||
uint64_t m_mod, vl_elms;
|
||||
|
||||
vl_elms = sve_cntw();
|
||||
|
||||
m_mod = ceil((double)M/(double)vl_elms) * vl_elms;
|
||||
|
||||
float *A_mod = (float *) malloc(m_mod*K*sizeof(float));
|
||||
@@ -48,7 +58,7 @@ void CNAME (BLASLONG M, BLASLONG N, BLASLONG K, float * __restrict A,\
|
||||
* of reading directly from vector (z) registers.
|
||||
* */
|
||||
asm volatile("" : : :"p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7",
|
||||
"p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",
|
||||
"p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
|
||||
"z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7",
|
||||
"z8", "z9", "z10", "z11", "z12", "z13", "z14", "z15",
|
||||
"z16", "z17", "z18", "z19", "z20", "z21", "z22", "z23",
|
||||
@@ -57,13 +67,13 @@ void CNAME (BLASLONG M, BLASLONG N, BLASLONG K, float * __restrict A,\
|
||||
/* Pre-process the left matrix to make it suitable for
|
||||
matrix sum of outer-product calculation
|
||||
*/
|
||||
sgemm_direct_sme1_preprocess(M, K, A, A_mod);
|
||||
SME1_PREPROCESS(M, K, A, A_mod);
|
||||
|
||||
/* Calculate C = A*B */
|
||||
sgemm_direct_sme1_2VLx2VL(M, K, N, A_mod, B, R);
|
||||
SME1_DIRECT2X2(M, K, N, A_mod, B, R);
|
||||
|
||||
asm volatile("" : : :"p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7",
|
||||
"p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",
|
||||
"p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15",
|
||||
"z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7",
|
||||
"z8", "z9", "z10", "z11", "z12", "z13", "z14", "z15",
|
||||
"z16", "z17", "z18", "z19", "z20", "z21", "z22", "z23",
|
||||
@@ -75,6 +85,16 @@ void CNAME (BLASLONG M, BLASLONG N, BLASLONG K, float * __restrict A,\
|
||||
|
||||
void CNAME (BLASLONG M, BLASLONG N, BLASLONG K, float * __restrict A,\
|
||||
BLASLONG strideA, float * __restrict B, BLASLONG strideB ,\
|
||||
float * __restrict R, BLASLONG strideR){}
|
||||
|
||||
float * __restrict R, BLASLONG strideR){
|
||||
fprintf(stderr,"EMPTY sgemm_kernel_direct should never be called \n");
|
||||
}
|
||||
void SME1_DIRECT2X2( uint64_t M , uint64_t K, uint64_t N,\
|
||||
const float * restrict A_base,\
|
||||
const float * restrict B_base,\
|
||||
const float * restrict C_base){};
|
||||
void SME1_PREPROCESS(uint64_t nbr, uint64_t nbc,\
|
||||
const float * restrict a, float * a_mod){};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "common.h"
|
||||
/* helper for the direct sgemm code adapted from Arjan van der Ven's x86_64 version */
|
||||
|
||||
int CNAME(BLASLONG M, BLASLONG N, BLASLONG K)
|
||||
{
|
||||
if (M<3) return 0;
|
||||
unsigned long long mnk = M * N * K;
|
||||
/* benchmark performance on M4 peaks around 512 and crosses the graph of the NEON SGEMM at about 3100 */
|
||||
if (mnk >= 3100L * 3100L * 3100L)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,16 +35,17 @@
|
||||
#define K_exit x15 //Exit condition for K loop
|
||||
#define M_cntr x16 //M loop counter
|
||||
#define C1 x17 //Constant1: N*(SVLs+1);SVLs-No. of 32-bit elements
|
||||
#define C2 x18 //Constant2: N + SVLs
|
||||
#define C3 x19 //Constant3: K*SVLs + SVLs
|
||||
#define C4 x20 //Constant4: SVLs-2
|
||||
#define C5 x21 //Constant5: K*SVLs
|
||||
#define C6 x22 //Constant6: N*SVLs
|
||||
#define C2 x19 //Constant2: N + SVLs
|
||||
#define C3 x20 //Constant3: K*SVLs + SVLs
|
||||
#define C4 x21 //Constant4: SVLs-2
|
||||
#define C5 x22 //Constant5: K*SVLs
|
||||
#define C6 x23 //Constant6: N*SVLs
|
||||
|
||||
.text
|
||||
.global sgemm_direct_sme1_2VLx2VL
|
||||
.global ASMNAME
|
||||
|
||||
sgemm_direct_sme1_2VLx2VL:
|
||||
ASMNAME:
|
||||
//sgemm_direct_sme1_2VLx2VL:
|
||||
|
||||
stp x19, x20, [sp, #-48]!
|
||||
stp x21, x22, [sp, #16]
|
||||
@@ -61,7 +62,7 @@
|
||||
add C2, N, C4 //N + SVLs
|
||||
add C3, C5, C4 //K*SVLs + SVLs
|
||||
whilelt p2.s, M_cntr, M //Tile 0,1 predicate (M dimension)
|
||||
sub w20, w20, #2 //SVLs-2
|
||||
sub w21, w21, #2 //SVLs-2
|
||||
|
||||
.M_Loop:
|
||||
incw M_cntr
|
||||
@@ -198,7 +199,7 @@ process_K_less_than_equal_2:
|
||||
st1w {za1h.s[w13, #0]}, p5, [Cptr1]
|
||||
st1w {za2h.s[w13, #0]}, p6, [Cptr0, C6, lsl #2]
|
||||
st1w {za3h.s[w13, #0]}, p7, [Cptr1, C6, lsl #2]
|
||||
cmp w13, w20
|
||||
cmp w13, w21
|
||||
b.mi .Loop_store_ZA
|
||||
psel p4, p0, p2.s[w13, 1]
|
||||
psel p5, p1, p2.s[w13, 1]
|
||||
@@ -211,12 +212,12 @@ process_K_less_than_equal_2:
|
||||
addvl Cptr, Cptr, #2
|
||||
addvl Bptr, Bptr, #1
|
||||
whilelt p0.b, Bptr, N_exit //1st Tile predicate (N dimension)
|
||||
b.first .N_Loop
|
||||
b.mi .N_Loop
|
||||
add A_base, A_base, C5, lsl #3 //A_base += 2*K*SVLs FP32 elements
|
||||
add C_base, C_base, C6, lsl #3 //C_base += 2*N*SVLs FP32 elements
|
||||
incw M_cntr
|
||||
whilelt p2.s, M_cntr, M //1st Tile predicate (M dimension)
|
||||
b.first .M_Loop
|
||||
b.mi .M_Loop
|
||||
|
||||
smstop
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
#define C6 x15 //Constant6: 3*ncol
|
||||
|
||||
.text
|
||||
.global sgemm_direct_sme1_preprocess
|
||||
.global ASMNAME //sgemm_direct_sme1_preprocess
|
||||
|
||||
sgemm_direct_sme1_preprocess:
|
||||
ASMNAME: //sgemm_direct_sme1_preprocess:
|
||||
|
||||
stp x19, x20, [sp, #-48]!
|
||||
stp x21, x22, [sp, #16]
|
||||
@@ -114,14 +114,14 @@
|
||||
|
||||
addvl mat_ptr0, mat_ptr0, #1 //mat_ptr0 += SVLb
|
||||
whilelt p8.b, mat_ptr0, inner_loop_exit
|
||||
b.first .Loop_process
|
||||
b.mi .Loop_process
|
||||
|
||||
add mat_mod, mat_mod, C3, lsl #2 //mat_mod+=SVLs*nbc FP32 elements
|
||||
add mat, mat, C3, lsl #2 //mat+=SVLs*nbc FP32 elements
|
||||
incw outer_loop_cntr
|
||||
|
||||
whilelt p0.s, outer_loop_cntr, nrow
|
||||
b.first .M_Loop
|
||||
b.mi .M_Loop
|
||||
|
||||
smstop
|
||||
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
// #include "sme_abi.h"
|
||||
#if defined(HAVE_SME)
|
||||
|
||||
#if defined(__ARM_FEATURE_SME) && defined(__clang__) && __clang_major__ >= 16
|
||||
#include <arm_sme.h>
|
||||
#endif
|
||||
|
||||
#if defined(DYNAMIC_ARCH)
|
||||
#define COMBINE(a,b) a ## b
|
||||
#define COMBINE2(a,b) COMBINE(a,b)
|
||||
#define SGEMM_PREPROCESS_BASE sgemm_direct_sme1_preprocess
|
||||
#define SGEMM_PREPROCESS COMBINE2(SGEMM_PREPROCESS_BASE,TS)
|
||||
#define SGEMM_DIRECT2X2_BASE sgemm_direct_alpha_beta_sme1_2VLx2VL
|
||||
#define SGEMM_DIRECT2X2 COMBINE2(SGEMM_DIRECT2X2_BASE,TS)
|
||||
#else
|
||||
#define SGEMM_PREPROCESS sgemm_direct_sme1_preprocess
|
||||
#define SGEMM_DIRECT2X2 sgemm_direct_alpha_beta_sme1_2VLx2VL
|
||||
#endif
|
||||
|
||||
/* Function prototypes */
|
||||
extern void SGEMM_PREPROCESS(uint64_t nbr, uint64_t nbc,\
|
||||
const float * restrict a, float * a_mod);
|
||||
|
||||
extern void SGEMM_DIRECT2X2(uint64_t m, uint64_t k, uint64_t n, const float* alpha,\
|
||||
const float *ba, const float *restrict bb, const float* beta,\
|
||||
float *restrict C);
|
||||
/* Function Definitions */
|
||||
static uint64_t sve_cntw() {
|
||||
uint64_t cnt;
|
||||
asm volatile(
|
||||
"rdsvl %[res], #1\n"
|
||||
"lsr %[res], %[res], #2\n"
|
||||
: [res] "=r" (cnt) ::
|
||||
);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#if defined(__ARM_FEATURE_SME) && defined(__ARM_FEATURE_LOCALLY_STREAMING) && defined(__clang__) && __clang_major__ >= 16
|
||||
|
||||
__arm_new("za") __arm_locally_streaming
|
||||
static void ssymm_direct_sme1_preprocessLU(uint64_t nbr, uint64_t nbc,
|
||||
const float *restrict a, float *restrict a_mod)
|
||||
{
|
||||
// const uint64_t num_rows = nbr;
|
||||
// const uint64_t num_cols = nbc;
|
||||
const uint64_t svl = svcntw();
|
||||
uint64_t row_batch = svl;
|
||||
|
||||
float *restrict pSrc;
|
||||
float *restrict pDst;
|
||||
for (uint64_t row_idx = 0; row_idx < nbr; row_idx += row_batch)
|
||||
{
|
||||
row_batch = MIN(row_batch, nbr - row_idx);
|
||||
|
||||
// Fill in the lower triangle and Transpose 1SVL x N panel of A
|
||||
uint64_t col_batch = svl;
|
||||
|
||||
for (uint64_t col_idx = 0; col_idx < nbc; col_idx += col_batch)
|
||||
{
|
||||
svzero_za();
|
||||
|
||||
if (col_idx == row_idx)
|
||||
{
|
||||
pSrc = &a[(row_idx)*nbc + col_idx];
|
||||
pDst = &a_mod[(col_idx)*svl + row_idx * nbc];
|
||||
// Load horizontal slices, filling lower elements
|
||||
const svbool_t pg_row = svwhilelt_b32_u64(col_idx, nbc);
|
||||
for (int64_t row = row_batch - 1; row >= 0; row--)
|
||||
{
|
||||
svld1_hor_za32(0, row, pg_row, &pSrc[row * nbc]);
|
||||
svld1_ver_za32(0, row, pg_row, &pSrc[row * nbc]);
|
||||
}
|
||||
// Save vertical slices
|
||||
col_batch = MIN(col_batch, nbc - col_idx);
|
||||
for (uint64_t col = 0; col < col_batch; col++)
|
||||
{
|
||||
svst1_ver_za32(0, col, svptrue_b32(), &pDst[col * svl]);
|
||||
}
|
||||
}
|
||||
else if (col_idx > row_idx)
|
||||
{
|
||||
pSrc = &a[(row_idx)*nbc + col_idx];
|
||||
pDst = &a_mod[(col_idx)*svl + row_idx * nbc];
|
||||
// Load horizontal slices
|
||||
const svbool_t pg_row = svwhilelt_b32_u64(col_idx, nbc);
|
||||
for (uint64_t row = 0; row < row_batch; row++)
|
||||
{
|
||||
svld1_hor_za32(0, row, pg_row, &pSrc[row * nbc]);
|
||||
}
|
||||
// Save vertical slices
|
||||
col_batch = MIN(col_batch, nbc - col_idx);
|
||||
for (uint64_t col = 0; col < col_batch; col++)
|
||||
{
|
||||
svst1_ver_za32(0, col, svptrue_b32(), &pDst[col * svl]);
|
||||
}
|
||||
}
|
||||
else if (col_idx < row_idx)
|
||||
{
|
||||
pSrc = &a[row_idx + col_idx * nbc];
|
||||
pDst = &a_mod[(col_idx)*svl + row_idx * nbc];
|
||||
// Load horizontal slices
|
||||
const svbool_t pg_row = svwhilelt_b32_u64(row_idx, nbc);
|
||||
for (uint64_t row = 0; row < svl; row++)
|
||||
{
|
||||
svld1_hor_za32(0, row, pg_row, &pSrc[row * nbc]);
|
||||
}
|
||||
// Save vertical slices
|
||||
col_batch = MIN(col_batch, nbc - col_idx);
|
||||
for (uint64_t col = 0; col < svl; col++)
|
||||
{
|
||||
svst1_hor_za32(0, col, svptrue_b32(), &pDst[col * svl]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
__arm_new("za") __arm_locally_streaming
|
||||
static void ssymm_direct_sme1_preprocessLL(uint64_t nbr, uint64_t nbc,
|
||||
const float *restrict a, float *restrict a_mod)
|
||||
{
|
||||
// const uint64_t num_rows = nbr;
|
||||
const uint64_t svl = svcntw();
|
||||
uint64_t row_batch = svl;
|
||||
|
||||
float *restrict pSrc;
|
||||
float *restrict pDst;
|
||||
for (uint64_t row_idx = 0; row_idx < nbr; row_idx += row_batch)
|
||||
{
|
||||
row_batch = MIN(row_batch, nbr - row_idx);
|
||||
|
||||
// Fill in the upper triangle and Transpose 1SVL x N panel of A
|
||||
uint64_t col_batch = svl;
|
||||
|
||||
for (uint64_t col_idx = 0; col_idx < nbc; col_idx += col_batch)
|
||||
{
|
||||
svzero_za();
|
||||
|
||||
if (col_idx == row_idx)
|
||||
{
|
||||
pSrc = &a[(row_idx)*nbc + col_idx];
|
||||
pDst = &a_mod[(col_idx)*svl + row_idx * nbc];
|
||||
// Load horizontal slices, filling upper elements
|
||||
const svbool_t pg_row = svwhilelt_b32_u64(col_idx, nbc);
|
||||
for (uint64_t row = 0; row < row_batch; row++)
|
||||
{
|
||||
svld1_hor_za32(0, row, pg_row, &pSrc[row * nbc]);
|
||||
svld1_ver_za32(0, row, pg_row, &pSrc[row * nbc]);
|
||||
}
|
||||
// Save vertical slices
|
||||
col_batch = MIN(col_batch, nbc - col_idx);
|
||||
for (uint64_t col = 0; col < col_batch; col++)
|
||||
{
|
||||
svst1_ver_za32(0, col, svptrue_b32(), &pDst[col * svl]);
|
||||
}
|
||||
}
|
||||
else if (col_idx > row_idx)
|
||||
{
|
||||
pSrc = &a[row_idx + col_idx * nbc];
|
||||
pDst = &a_mod[(col_idx)*svl + row_idx * nbc];
|
||||
// Load horizontal slices
|
||||
const svbool_t pg_row = svptrue_b32();
|
||||
for (uint64_t row = 0; row < row_batch; row++)
|
||||
{
|
||||
svld1_hor_za32(0, row, pg_row, &pSrc[row * nbc]);
|
||||
}
|
||||
// Save vertical slices
|
||||
col_batch = MIN(col_batch, nbc - col_idx);
|
||||
for (uint64_t col = 0; col < col_batch; col++)
|
||||
{
|
||||
svst1_hor_za32(0, col, svptrue_b32(), &pDst[col * svl]);
|
||||
}
|
||||
}
|
||||
else if (col_idx < row_idx)
|
||||
{
|
||||
pSrc = &a[(row_idx)*nbc + col_idx];
|
||||
pDst = &a_mod[(col_idx)*svl + row_idx * nbc];
|
||||
// Load horizontal slices
|
||||
const svbool_t pg_row = svwhilelt_b32_u64(col_idx, nbc);
|
||||
for (uint64_t row = 0; row < row_batch; row++)
|
||||
{
|
||||
svld1_hor_za32(0, row, pg_row, &pSrc[row * nbc]);
|
||||
}
|
||||
// Save vertical slices
|
||||
col_batch = MIN(col_batch, nbc - col_idx);
|
||||
for (uint64_t col = 0; col < col_batch; col++)
|
||||
{
|
||||
svst1_ver_za32(0, col, svptrue_b32(), &pDst[col * svl]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void ssymm_direct_sme1_preprocessLU(uint64_t nbr, uint64_t nbc,
|
||||
const float *restrict a, float *restrict a_mod){}
|
||||
static void ssymm_direct_sme1_preprocessLL(uint64_t nbr, uint64_t nbc,
|
||||
const float *restrict a, float *restrict a_mod){}
|
||||
#endif
|
||||
|
||||
//
|
||||
void CNAME(BLASLONG M, BLASLONG N, float alpha, float *__restrict A,
|
||||
BLASLONG strideA, float *__restrict B, BLASLONG strideB,
|
||||
float beta, float *__restrict R, BLASLONG strideR)
|
||||
{
|
||||
uint64_t vl_elms = sve_cntw(); // vl_elem = 16
|
||||
uint64_t m_mod = ceil((double)M / (double)vl_elms) * vl_elms;
|
||||
|
||||
/* Pre-process the left matrix to make it suitable for
|
||||
matrix sum of outer-product calculation
|
||||
*/
|
||||
float *A_mod = (float *)malloc(m_mod * M * sizeof(float));
|
||||
|
||||
#if defined(UPPER)
|
||||
ssymm_direct_sme1_preprocessLU(M, M, A, A_mod);
|
||||
#elif defined(LOWER)
|
||||
ssymm_direct_sme1_preprocessLL(M, M, A, A_mod);
|
||||
#endif
|
||||
|
||||
/* Calculate C = alpha*A*B + beta*C */
|
||||
SGEMM_DIRECT2X2(M, M, N, &alpha, A_mod, B, &beta, R);
|
||||
free(A_mod);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void CNAME (BLASLONG M, BLASLONG N, float alpha, float * __restrict A,\
|
||||
BLASLONG strideA, float * __restrict B, BLASLONG strideB ,\
|
||||
float beta, float * __restrict R, BLASLONG strideR){}
|
||||
|
||||
#endif
|
||||
+298
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
|
||||
#if defined(DYNAMIC_ARCH)
|
||||
#define COMBINE(a,b) a ## b
|
||||
#define COMBINE2(a,b) COMBINE(a,b)
|
||||
#define SGEMM_PREPROCESS_BASE sgemm_direct_sme1_preprocess
|
||||
#define SGEMM_PREPROCESS COMBINE2(SGEMM_PREPROCESS_BASE,TS)
|
||||
#define SGEMM_DIRECT2X2_BASE sgemm_direct_alpha_beta_sme1_2VLx2VL
|
||||
#define SGEMM_DIRECT2X2 COMBINE2(SGEMM_DIRECT2X2_BASE,TS)
|
||||
#else
|
||||
#define SGEMM_PREPROCESS sgemm_direct_sme1_preprocess
|
||||
#define SGEMM_DIRECT2X2 sgemm_direct_alpha_beta_sme1_2VLx2VL
|
||||
#endif
|
||||
#if defined(HAVE_SME)
|
||||
|
||||
#if defined(__ARM_FEATURE_SME) && defined(__clang__) && __clang_major__ >= 16
|
||||
#include <arm_sme.h>
|
||||
#endif
|
||||
|
||||
/* Function prototypes */
|
||||
extern void SGEMM_PREPROCESS(uint64_t nbr, uint64_t nbc,\
|
||||
const float * restrict a, float * a_mod) ;
|
||||
|
||||
/* Function Definitions */
|
||||
static uint64_t sve_cntw() {
|
||||
uint64_t cnt;
|
||||
asm volatile(
|
||||
"rdsvl %[res], #1\n"
|
||||
"lsr %[res], %[res], #2\n"
|
||||
: [res] "=r" (cnt) ::
|
||||
);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#if defined(__ARM_FEATURE_SME) && defined(__ARM_FEATURE_LOCALLY_STREAMING) && defined(__clang__) && __clang_major__ >= 16
|
||||
// Outer product kernel.
|
||||
// Computes a 2SVL x 2SVL block of C, utilizing all four FP32 tiles of ZA.
|
||||
__attribute__((always_inline)) inline void
|
||||
kernel_2x2(const float *A, float *B_T, const float *B, float *A_T, float *C, size_t shared_dim,
|
||||
size_t ldc, size_t block_rows, size_t block_cols, float alpha,
|
||||
float beta, uint64_t row_idx, uint64_t col_idx)
|
||||
__arm_out("za") __arm_streaming {
|
||||
|
||||
const uint64_t svl = svcntw();
|
||||
size_t ldb = ldc;
|
||||
// Predicate set-up
|
||||
svbool_t pg = svptrue_b32();
|
||||
svbool_t pg_a_0 = svwhilelt_b32_u64(0, block_rows);
|
||||
svbool_t pg_a_1 = svwhilelt_b32_u64(svl, block_rows);
|
||||
|
||||
svbool_t pg_b_0 = svwhilelt_b32_u64(0, block_cols);
|
||||
svbool_t pg_b_1 = svwhilelt_b32_u64(svl, block_cols);
|
||||
|
||||
#define pg_c_0 pg_b_0
|
||||
#define pg_c_1 pg_b_1
|
||||
|
||||
svzero_za();
|
||||
svfloat32_t beta_vec = svdup_f32(beta);
|
||||
|
||||
// Load C to ZA
|
||||
for (size_t i = 0; i < MIN(svl, block_rows); i++) {
|
||||
svfloat32_t row_c_0 = svld1(pg_c_0, &C[i * ldc]);
|
||||
row_c_0 = svmul_x(pg, beta_vec, row_c_0);
|
||||
svwrite_hor_za32_f32_m(/*tile*/0, /*slice*/i, pg_c_0, row_c_0);
|
||||
|
||||
svfloat32_t row_c_1 = svld1(pg_c_1, &C[i * ldc + svl]);
|
||||
row_c_1 = svmul_x(pg, beta_vec, row_c_1);
|
||||
svwrite_hor_za32_f32_m(/*tile*/1, /*slice*/i, pg_c_1, row_c_1);
|
||||
}
|
||||
for (size_t i = svl; i < block_rows; i++) {
|
||||
svfloat32_t row_c_0 = svld1(pg_c_0, &C[i * ldc]);
|
||||
row_c_0 = svmul_x(pg, beta_vec, row_c_0);
|
||||
svwrite_hor_za32_f32_m(/*tile*/2, /*slice*/i, pg_c_0, row_c_0);
|
||||
|
||||
svfloat32_t row_c_1 = svld1(pg_c_1, &C[i * ldc + svl]);
|
||||
row_c_1 = svmul_x(pg, beta_vec, row_c_1);
|
||||
svwrite_hor_za32_f32_m(/*tile*/3, /*slice*/i, pg_c_1, row_c_1);
|
||||
}
|
||||
|
||||
svfloat32_t alpha_vec = svdup_f32(alpha);
|
||||
// Iterate through shared dimension (K)
|
||||
for (size_t k = 0; k < shared_dim; k++) {
|
||||
#if !defined(TRANSA)
|
||||
// Computes alpha*A*B**T
|
||||
// Load column of A
|
||||
svfloat32_t col_a_0 = svld1(pg_a_0, &A[k * svl]);
|
||||
col_a_0 = svmul_x(pg, alpha_vec, col_a_0);
|
||||
svfloat32_t col_a_1 = svld1(pg_a_1, &A[(k + shared_dim) * svl]);
|
||||
col_a_1 = svmul_x(pg, alpha_vec, col_a_1);
|
||||
|
||||
// Load row of B**T
|
||||
svfloat32_t row_b_0 = svld1(pg_b_0, &B_T[k * svl]);
|
||||
svfloat32_t row_b_1 = svld1(pg_b_1, &B_T[(k + shared_dim) * svl]);
|
||||
#else
|
||||
// Computes alpha*A**T*B
|
||||
// Load column of A**T
|
||||
svfloat32_t col_a_0 = svld1(pg_a_0, &A[k * ldb]);
|
||||
col_a_0 = svmul_x(pg, alpha_vec, col_a_0);
|
||||
|
||||
svfloat32_t col_a_1 = svld1(pg_a_1, &A[k * ldb + svl]);
|
||||
col_a_1 = svmul_x(pg, alpha_vec, col_a_1);
|
||||
|
||||
// Load row of B
|
||||
svfloat32_t row_b_0 = svld1(pg_b_0, &B_T[k * ldb]);
|
||||
svfloat32_t row_b_1 = svld1(pg_b_1, &B_T[k * ldb + svl]);
|
||||
#endif
|
||||
// Perform outer product
|
||||
svmopa_za32_m(/*tile*/0, pg, pg, col_a_0, row_b_0);
|
||||
svmopa_za32_m(/*tile*/1, pg, pg, col_a_0, row_b_1);
|
||||
svmopa_za32_m(/*tile*/2, pg, pg, col_a_1, row_b_0);
|
||||
svmopa_za32_m(/*tile*/3, pg, pg, col_a_1, row_b_1);
|
||||
|
||||
#if !defined(TRANSA)
|
||||
// Computes alpha*B*A**T
|
||||
// Load column of B
|
||||
col_a_0 = svld1(pg_a_0, &B[k * svl]);
|
||||
col_a_0 = svmul_x(pg, alpha_vec, col_a_0);
|
||||
col_a_1 = svld1(pg_a_1, &B[(k + shared_dim) * svl]);
|
||||
col_a_1 = svmul_x(pg, alpha_vec, col_a_1);
|
||||
|
||||
// Load row of A**T
|
||||
row_b_0 = svld1(pg_b_0, &A_T[k * svl]);
|
||||
row_b_1 = svld1(pg_b_1, &A_T[(k + shared_dim) * svl]);
|
||||
#else
|
||||
// Computes alpha*B**T*A
|
||||
// Load column of B**T
|
||||
col_a_0 = svld1(pg_a_0, &B[k * ldb]);
|
||||
col_a_0 = svmul_x(pg, alpha_vec, col_a_0);
|
||||
|
||||
col_a_1 = svld1(pg_a_1, &B[k * ldb + svl]);
|
||||
col_a_1 = svmul_x(pg, alpha_vec, col_a_1);
|
||||
|
||||
// Load row of A
|
||||
row_b_0 = svld1(pg_b_0, &A_T[k * ldb]);
|
||||
row_b_1 = svld1(pg_b_1, &A_T[k * ldb + svl]);
|
||||
#endif
|
||||
// Perform outer product
|
||||
svmopa_za32_m(/*tile*/0, pg, pg, col_a_0, row_b_0);
|
||||
svmopa_za32_m(/*tile*/1, pg, pg, col_a_0, row_b_1);
|
||||
svmopa_za32_m(/*tile*/2, pg, pg, col_a_1, row_b_0);
|
||||
svmopa_za32_m(/*tile*/3, pg, pg, col_a_1, row_b_1);
|
||||
}
|
||||
|
||||
#if defined(UPPER)
|
||||
#define pg_c_0_full pg_c_0
|
||||
#define pg_c_1_full pg_c_1
|
||||
|
||||
bool need_update_pg_b = true;
|
||||
size_t last_invalid_index = col_idx - row_idx;
|
||||
// For Upper, If col_idx - row_idx >= 2*svl, we don't need to update the predicate due to all elements above the digonal
|
||||
if (col_idx - row_idx >= 2*svl) {
|
||||
need_update_pg_b = false;
|
||||
}
|
||||
// Store to C from ZA
|
||||
for (size_t i = 0; i < MIN(svl, block_rows); i++, last_invalid_index++) {
|
||||
if (need_update_pg_b) {
|
||||
pg_c_0 = svnot_b_z(pg_c_0_full, svwhilelt_b32_u64(0, last_invalid_index));
|
||||
pg_c_1 = svnot_b_z(pg_c_1_full, svwhilelt_b32_u64(svl, last_invalid_index));
|
||||
}
|
||||
svst1_hor_za32(/*tile*/0, /*slice*/i, pg_c_0, &C[i * ldc]);
|
||||
svst1_hor_za32(/*tile*/1, /*slice*/i, pg_c_1, &C[i * ldc + svl]);
|
||||
}
|
||||
for (size_t i = svl; i < block_rows; i++,last_invalid_index++) {
|
||||
if (need_update_pg_b) {
|
||||
pg_c_0 = svnot_b_z(pg_c_0_full, svwhilelt_b32_u64(0, last_invalid_index));
|
||||
pg_c_1 = svnot_b_z(pg_c_1_full, svwhilelt_b32_u64(svl, last_invalid_index));
|
||||
}
|
||||
svst1_hor_za32(/*tile*/2, /*slice*/i, pg_c_0, &C[i * ldc]);
|
||||
svst1_hor_za32(/*tile*/3, /*slice*/i, pg_c_1, &C[i * ldc + svl]);
|
||||
}
|
||||
#else
|
||||
// Store to C from ZA
|
||||
size_t valid_index = row_idx - col_idx + 1;
|
||||
for (size_t i = 0; i < MIN(svl, block_rows); i++, valid_index++) {
|
||||
pg_c_0 = svwhilelt_b32_u64(0, MIN(valid_index, block_cols));
|
||||
pg_c_1 = svwhilelt_b32_u64(svl, MIN(valid_index, block_cols));
|
||||
svst1_hor_za32(/*tile*/0, /*slice*/i, pg_c_0, &C[i * ldc]);
|
||||
svst1_hor_za32(/*tile*/1, /*slice*/i, pg_c_1, &C[i * ldc + svl]);
|
||||
}
|
||||
for (size_t i = svl; i < block_rows; i++, valid_index++) {
|
||||
pg_c_0 = svwhilelt_b32_u64(0, MIN(valid_index, block_cols));
|
||||
pg_c_1 = svwhilelt_b32_u64(svl, MIN(valid_index, block_cols));
|
||||
svst1_hor_za32(/*tile*/2, /*slice*/i, pg_c_0, &C[i * ldc]);
|
||||
svst1_hor_za32(/*tile*/3, /*slice*/i, pg_c_1, &C[i * ldc + svl]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
__arm_new("za") __arm_locally_streaming
|
||||
static void ssyr2k_direct_sme1_2VLx2VL(uint64_t n, uint64_t k, const float* alpha,\
|
||||
const float *ba, const float *bb, const float* beta, float *restrict bc) {
|
||||
const uint64_t num_rows = n;
|
||||
const uint64_t num_cols = n;
|
||||
|
||||
const float *restrict a_ptr = ba;
|
||||
const float *restrict b_ptr = bb;
|
||||
float *restrict c_ptr = bc;
|
||||
|
||||
const uint64_t svl = svcntw();
|
||||
const uint64_t ldc = n;
|
||||
|
||||
// Block over rows of C (panels of A)
|
||||
uint64_t row_idx = 0;
|
||||
|
||||
// 2x2 loop
|
||||
uint64_t row_batch = 2*svl;
|
||||
|
||||
// Block over row dimension of C
|
||||
for (; row_idx < num_rows; row_idx += row_batch) {
|
||||
row_batch = MIN(row_batch, num_rows - row_idx);
|
||||
uint64_t col_batch = 2*svl;
|
||||
#if defined(UPPER)
|
||||
// for UPLO is upper, Start from column col_idx = rows_index to ensure we only process the upper triangle (col_idx >= rows_index)
|
||||
for (uint64_t col_idx = row_idx; col_idx < num_cols; col_idx += col_batch) {
|
||||
col_batch = MIN(col_batch, num_cols - col_idx);
|
||||
#else
|
||||
// for UPLO is lower, we only process the lower triangle part (col_idx <= row_idxx)
|
||||
for (uint64_t col_idx = 0; col_idx < num_cols && col_idx <= row_idx; col_idx += col_batch) {
|
||||
#endif
|
||||
col_batch = MIN(col_batch, num_cols - col_idx);
|
||||
#if !defined(TRANSA)
|
||||
kernel_2x2(&a_ptr[row_idx * k], &b_ptr[col_idx * k], &b_ptr[row_idx * k], &a_ptr[col_idx * k],
|
||||
&c_ptr[row_idx * ldc + col_idx], k,
|
||||
ldc, row_batch, col_batch, *alpha, *beta, row_idx, col_idx);
|
||||
#else
|
||||
kernel_2x2(&a_ptr[row_idx], &b_ptr[col_idx], &b_ptr[row_idx], &a_ptr[col_idx],
|
||||
&c_ptr[row_idx * ldc + col_idx], k,
|
||||
ldc, row_batch, col_batch, *alpha, *beta, row_idx, col_idx);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
static void ssyr2k_direct_sme1_2VLx2VL(uint64_t n, uint64_t k, const float* alpha,\
|
||||
const float *ba, const float *bb, const float* beta, float *restrict bc){}
|
||||
#endif
|
||||
|
||||
void CNAME (BLASLONG N, BLASLONG K, float alpha, float * __restrict A, \
|
||||
BLASLONG strideA, float * __restrict B, BLASLONG strideB, \
|
||||
float beta, float * __restrict R, BLASLONG strideR)
|
||||
{
|
||||
#if !defined(TRANSA)
|
||||
uint64_t n_mod, vl_elms;
|
||||
|
||||
vl_elms = sve_cntw();
|
||||
|
||||
n_mod = ceil((double)N/(double)vl_elms) * vl_elms;
|
||||
|
||||
float *A_mod = (float *) malloc(n_mod*K*sizeof(float));
|
||||
float *B_mod = (float *) malloc(n_mod*K*sizeof(float));
|
||||
|
||||
/* Prevent compiler optimization by reading from memory instead
|
||||
* of reading directly from vector (z) registers.
|
||||
* */
|
||||
asm volatile("" : : :"p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7",
|
||||
"p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",
|
||||
"z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7",
|
||||
"z8", "z9", "z10", "z11", "z12", "z13", "z14", "z15",
|
||||
"z16", "z17", "z18", "z19", "z20", "z21", "z22", "z23",
|
||||
"z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31");
|
||||
|
||||
/* Pre-process the left matrix to make it suitable for
|
||||
matrix sum of outer-product calculation
|
||||
*/
|
||||
SGEMM_PREPROCESS(N, K, A, A_mod);
|
||||
SGEMM_PREPROCESS(N, K, B, B_mod);
|
||||
asm volatile("" : : :"p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7",
|
||||
"p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",
|
||||
"z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7",
|
||||
"z8", "z9", "z10", "z11", "z12", "z13", "z14", "z15",
|
||||
"z16", "z17", "z18", "z19", "z20", "z21", "z22", "z23",
|
||||
"z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31");
|
||||
|
||||
ssyr2k_direct_sme1_2VLx2VL(N, K, &alpha, A_mod, B_mod, &beta, R);
|
||||
free(A_mod);
|
||||
free(B_mod);
|
||||
#else
|
||||
ssyr2k_direct_sme1_2VLx2VL(N, K, &alpha, A, B, &beta, R);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
|
||||
void CNAME (BLASLONG N, BLASLONG K, float alpha, float * __restrict A, \
|
||||
BLASLONG strideA, float * __restrict B, BLASLONG strideB, \
|
||||
float beta, float * __restrict C, BLASLONG strideC){}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#if defined(HAVE_SME)
|
||||
|
||||
#if defined(DYNAMIC_ARCH)
|
||||
#define COMBINE(a,b) a ## b
|
||||
#define COMBINE2(a,b) COMBINE(a,b)
|
||||
#define SGEMM_PREPROCESS_BASE sgemm_direct_sme1_preprocess
|
||||
#define SGEMM_PREPROCESS COMBINE2(SGEMM_PREPROCESS_BASE,TS)
|
||||
#define SGEMM_DIRECT2X2_BASE sgemm_direct_alpha_beta_sme1_2VLx2VL
|
||||
#define SGEMM_DIRECT2X2 COMBINE2(SGEMM_DIRECT2X2_BASE,TS)
|
||||
#else
|
||||
#define SGEMM_PREPROCESS sgemm_direct_sme1_preprocess
|
||||
#define SGEMM_DIRECT2X2 sgemm_direct_alpha_beta_sme1_2VLx2VL
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_FEATURE_SME) && defined(__clang__) && __clang_major__ >= 16
|
||||
#include <arm_sme.h>
|
||||
#endif
|
||||
|
||||
/* Function prototypes */
|
||||
extern void SGEMM_PREPROCESS (uint64_t nbr, uint64_t nbc,\
|
||||
|
||||
const float * restrict a, float * a_mod) ;
|
||||
|
||||
/* Function Definitions */
|
||||
static uint64_t sve_cntw() {
|
||||
uint64_t cnt;
|
||||
asm volatile(
|
||||
"rdsvl %[res], #1\n"
|
||||
"lsr %[res], %[res], #2\n"
|
||||
: [res] "=r" (cnt) ::
|
||||
);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#if defined(__ARM_FEATURE_SME) && defined(__ARM_FEATURE_LOCALLY_STREAMING) && defined(__clang__) && __clang_major__ >= 16
|
||||
// Outer product kernel.
|
||||
// Computes a 2SVL x 2SVL block of C, utilizing all four FP32 tiles of ZA.
|
||||
__attribute__((always_inline)) inline void
|
||||
kernel_2x2(const float *A, float *B, float *C, size_t shared_dim,
|
||||
size_t ldc, size_t block_rows, size_t block_cols, float alpha,
|
||||
float beta, uint64_t row_idx, uint64_t col_idx)
|
||||
__arm_out("za") __arm_streaming {
|
||||
|
||||
const uint64_t svl = svcntw();
|
||||
size_t ldb = ldc;
|
||||
// Predicate set-up
|
||||
svbool_t pg = svptrue_b32();
|
||||
svbool_t pg_a_0 = svwhilelt_b32_u64(0, block_rows);
|
||||
svbool_t pg_a_1 = svwhilelt_b32_u64(svl, block_rows);
|
||||
|
||||
svbool_t pg_b_0 = svwhilelt_b32_u64(0, block_cols);
|
||||
svbool_t pg_b_1 = svwhilelt_b32_u64(svl, block_cols);
|
||||
|
||||
#define pg_c_0 pg_b_0
|
||||
#define pg_c_1 pg_b_1
|
||||
|
||||
svzero_za();
|
||||
svfloat32_t beta_vec = svdup_f32(beta);
|
||||
|
||||
// Load C to ZA
|
||||
for (size_t i = 0; i < MIN(svl, block_rows); i++) {
|
||||
svfloat32_t row_c_0 = svld1(pg_c_0, &C[i * ldc]);
|
||||
row_c_0 = svmul_x(pg, beta_vec, row_c_0);
|
||||
svwrite_hor_za32_f32_m(/*tile*/0, /*slice*/i, pg_c_0, row_c_0);
|
||||
|
||||
svfloat32_t row_c_1 = svld1(pg_c_1, &C[i * ldc + svl]);
|
||||
row_c_1 = svmul_x(pg, beta_vec, row_c_1);
|
||||
svwrite_hor_za32_f32_m(/*tile*/1, /*slice*/i, pg_c_1, row_c_1);
|
||||
}
|
||||
for (size_t i = svl; i < block_rows; i++) {
|
||||
svfloat32_t row_c_0 = svld1(pg_c_0, &C[i * ldc]);
|
||||
row_c_0 = svmul_x(pg, beta_vec, row_c_0);
|
||||
svwrite_hor_za32_f32_m(/*tile*/2, /*slice*/i, pg_c_0, row_c_0);
|
||||
|
||||
svfloat32_t row_c_1 = svld1(pg_c_1, &C[i * ldc + svl]);
|
||||
row_c_1 = svmul_x(pg, beta_vec, row_c_1);
|
||||
svwrite_hor_za32_f32_m(/*tile*/3, /*slice*/i, pg_c_1, row_c_1);
|
||||
}
|
||||
|
||||
svfloat32_t alpha_vec = svdup_f32(alpha);
|
||||
// Iterate through shared dimension (K)
|
||||
for (size_t k = 0; k < shared_dim; k++) {
|
||||
#if !defined(TRANSA)
|
||||
// Load column of A
|
||||
svfloat32_t col_a_0 = svld1(pg_a_0, &A[k * svl]);
|
||||
col_a_0 = svmul_x(pg, alpha_vec, col_a_0);
|
||||
svfloat32_t col_a_1 = svld1(pg_a_1, &A[(k + shared_dim) * svl]);
|
||||
col_a_1 = svmul_x(pg, alpha_vec, col_a_1);
|
||||
|
||||
// Load row of A**T
|
||||
svfloat32_t row_b_0 = svld1(pg_b_0, &B[k * svl]);
|
||||
svfloat32_t row_b_1 = svld1(pg_b_1, &B[(k + shared_dim) * svl]);
|
||||
#else
|
||||
// Load column of A**T
|
||||
svfloat32_t col_a_0 = svld1(pg_a_0, &A[k * ldb]);
|
||||
col_a_0 = svmul_x(pg, alpha_vec, col_a_0);
|
||||
|
||||
svfloat32_t col_a_1 = svld1(pg_a_1, &A[k * ldb + svl]);
|
||||
col_a_1 = svmul_x(pg, alpha_vec, col_a_1);
|
||||
|
||||
// Load row of A
|
||||
svfloat32_t row_b_0 = svld1(pg_b_0, &B[k * ldb]);
|
||||
svfloat32_t row_b_1 = svld1(pg_b_1, &B[k * ldb + svl]);
|
||||
#endif
|
||||
// Perform outer product
|
||||
svmopa_za32_m(/*tile*/0, pg, pg, col_a_0, row_b_0);
|
||||
svmopa_za32_m(/*tile*/1, pg, pg, col_a_0, row_b_1);
|
||||
svmopa_za32_m(/*tile*/2, pg, pg, col_a_1, row_b_0);
|
||||
svmopa_za32_m(/*tile*/3, pg, pg, col_a_1, row_b_1);
|
||||
}
|
||||
|
||||
#if defined(UPPER)
|
||||
#define pg_c_0_full pg_c_0
|
||||
#define pg_c_1_full pg_c_1
|
||||
|
||||
bool need_update_pg_b = true;
|
||||
size_t last_invalid_index = col_idx - row_idx;
|
||||
// For Upper, If col_idx - row_idx >= 2*svl, we don't need to update the predicate due to all elements above the digonal
|
||||
if (col_idx - row_idx >= 2*svl) {
|
||||
need_update_pg_b = false;
|
||||
}
|
||||
// Store to C from ZA
|
||||
for (size_t i = 0; i < MIN(svl, block_rows); i++, last_invalid_index++) {
|
||||
if (need_update_pg_b) {
|
||||
pg_c_0 = svnot_b_z(pg_c_0_full, svwhilelt_b32_u64(0, last_invalid_index));
|
||||
pg_c_1 = svnot_b_z(pg_c_1_full, svwhilelt_b32_u64(svl, last_invalid_index));
|
||||
}
|
||||
|
||||
svst1_hor_za32(/*tile*/0, /*slice*/i, pg_c_0, &C[i * ldc]);
|
||||
svst1_hor_za32(/*tile*/1, /*slice*/i, pg_c_1, &C[i * ldc + svl]);
|
||||
}
|
||||
for (size_t i = svl; i < block_rows; i++,last_invalid_index++) {
|
||||
if (need_update_pg_b) {
|
||||
pg_c_0 = svnot_b_z(pg_c_0_full, svwhilelt_b32_u64(0, last_invalid_index));
|
||||
pg_c_1 = svnot_b_z(pg_c_1_full, svwhilelt_b32_u64(svl, last_invalid_index));
|
||||
}
|
||||
svst1_hor_za32(/*tile*/2, /*slice*/i, pg_c_0, &C[i * ldc]);
|
||||
svst1_hor_za32(/*tile*/3, /*slice*/i, pg_c_1, &C[i * ldc + svl]);
|
||||
}
|
||||
#else
|
||||
// Store to C from ZA
|
||||
size_t valid_index = row_idx - col_idx + 1;
|
||||
for (size_t i = 0; i < MIN(svl, block_rows); i++, valid_index++) {
|
||||
pg_c_0 = svwhilelt_b32_u64(0, MIN(valid_index, block_cols));
|
||||
pg_c_1 = svwhilelt_b32_u64(svl, MIN(valid_index, block_cols));
|
||||
svst1_hor_za32(/*tile*/0, /*slice*/i, pg_c_0, &C[i * ldc]);
|
||||
svst1_hor_za32(/*tile*/1, /*slice*/i, pg_c_1, &C[i * ldc + svl]);
|
||||
}
|
||||
for (size_t i = svl; i < block_rows; i++, valid_index++) {
|
||||
pg_c_0 = svwhilelt_b32_u64(0, MIN(valid_index, block_cols));
|
||||
pg_c_1 = svwhilelt_b32_u64(svl, MIN(valid_index, block_cols));
|
||||
svst1_hor_za32(/*tile*/2, /*slice*/i, pg_c_0, &C[i * ldc]);
|
||||
svst1_hor_za32(/*tile*/3, /*slice*/i, pg_c_1, &C[i * ldc + svl]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
__arm_new("za") __arm_locally_streaming
|
||||
static void ssyrk_direct_sme1_2VLx2VL(uint64_t n, uint64_t k, const float* alpha,\
|
||||
const float *ba, const float* beta, float *restrict bc) {
|
||||
const uint64_t num_rows = n;
|
||||
const uint64_t num_cols = n;
|
||||
|
||||
const float *restrict a_ptr = ba;
|
||||
const float *restrict b_ptr = ba;
|
||||
float *restrict c_ptr = bc;
|
||||
|
||||
const uint64_t svl = svcntw();
|
||||
const uint64_t ldc = n;
|
||||
|
||||
// Block over rows of C (panels of A)
|
||||
uint64_t row_idx = 0;
|
||||
|
||||
// 2x2 loop
|
||||
uint64_t row_batch = 2*svl;
|
||||
|
||||
// Block over row dimension of C
|
||||
for (; row_idx < num_rows; row_idx += row_batch) {
|
||||
row_batch = MIN(row_batch, num_rows - row_idx);
|
||||
uint64_t col_batch = 2*svl;
|
||||
#if defined(UPPER)
|
||||
// for UPLO is upper, Start from column col_idx = rows_index to ensure we only process the upper triangle (col_idx >= rows_index)
|
||||
for (uint64_t col_idx = row_idx; col_idx < num_cols; col_idx += col_batch) {
|
||||
col_batch = MIN(col_batch, num_cols - col_idx);
|
||||
#else
|
||||
// for UPLO is lower, we only process the lower triangle part (col_idx <= row_idxx)
|
||||
for (uint64_t col_idx = 0; col_idx < num_cols && col_idx <= row_idx; col_idx += col_batch) {
|
||||
#endif
|
||||
col_batch = MIN(col_batch, num_cols - col_idx);
|
||||
#if !defined(TRANSA)
|
||||
kernel_2x2(&a_ptr[row_idx * k], &b_ptr[col_idx * k],
|
||||
&c_ptr[row_idx * ldc + col_idx], k,
|
||||
ldc, row_batch, col_batch, *alpha, *beta, row_idx, col_idx);
|
||||
#else
|
||||
kernel_2x2(&a_ptr[row_idx], &b_ptr[col_idx],
|
||||
&c_ptr[row_idx * ldc + col_idx], k,
|
||||
ldc, row_batch, col_batch, *alpha, *beta, row_idx, col_idx);
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
static void ssyrk_direct_sme1_2VLx2VL(uint64_t n, uint64_t k, const float* alpha,\
|
||||
const float *ba, const float* beta, float *restrict bc){}
|
||||
#endif
|
||||
|
||||
void CNAME (BLASLONG N, BLASLONG K, float alpha, float * __restrict A,\
|
||||
BLASLONG strideA, float beta, float * __restrict C, BLASLONG strideC){
|
||||
#if !defined(TRANSA)
|
||||
uint64_t n_mod, vl_elms;
|
||||
|
||||
vl_elms = sve_cntw();
|
||||
|
||||
n_mod = ceil((double)N/(double)vl_elms) * vl_elms;
|
||||
|
||||
float *A_mod = (float *) malloc(n_mod*K*sizeof(float));
|
||||
|
||||
/* Prevent compiler optimization by reading from memory instead
|
||||
* of reading directly from vector (z) registers.
|
||||
* */
|
||||
asm volatile("" : : :"p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7",
|
||||
"p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",
|
||||
"z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7",
|
||||
"z8", "z9", "z10", "z11", "z12", "z13", "z14", "z15",
|
||||
"z16", "z17", "z18", "z19", "z20", "z21", "z22", "z23",
|
||||
"z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31");
|
||||
|
||||
/* Pre-process the left matrix to make it suitable for
|
||||
matrix sum of outer-product calculation
|
||||
*/
|
||||
SGEMM_PREPROCESS (N, K, A, A_mod);
|
||||
asm volatile("" : : :"p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7",
|
||||
"p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",
|
||||
"z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7",
|
||||
"z8", "z9", "z10", "z11", "z12", "z13", "z14", "z15",
|
||||
"z16", "z17", "z18", "z19", "z20", "z21", "z22", "z23",
|
||||
"z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31");
|
||||
ssyrk_direct_sme1_2VLx2VL(N, K, &alpha, A_mod, &beta, C);
|
||||
free(A_mod);
|
||||
#else
|
||||
ssyrk_direct_sme1_2VLx2VL(N, K, &alpha, A, &beta, C);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void CNAME (BLASLONG N, BLASLONG K, float alpha, float * __restrict A,\
|
||||
BLASLONG strideA, float beta, float * __restrict C, BLASLONG strideC){
|
||||
fprintf(stderr,"empty ssyrk_direct kernel should never be called\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
//#include "sme_abi.h"
|
||||
#if defined(HAVE_SME)
|
||||
|
||||
#if defined(__ARM_FEATURE_SME) && defined(__clang__) && __clang_major__ >= 16
|
||||
#include <arm_sme.h>
|
||||
#endif
|
||||
|
||||
/* Function Definitions */
|
||||
static uint64_t sve_cntw() {
|
||||
uint64_t cnt;
|
||||
asm volatile(
|
||||
"rdsvl %[res], #1\n"
|
||||
"lsr %[res], %[res], #2\n"
|
||||
: [res] "=r" (cnt) ::
|
||||
);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#if defined(__ARM_FEATURE_SME) && defined(__ARM_FEATURE_LOCALLY_STREAMING) && defined(__clang__) && __clang_major__ >= 16
|
||||
|
||||
// Transpose 1SVL x N panel of A
|
||||
__attribute__((always_inline))
|
||||
inline static void transpose_panel_lower(const float *restrict a, float *restrict b,
|
||||
uint64_t rows, uint64_t cols,
|
||||
uint64_t a_step, uint64_t rows_index)
|
||||
__arm_out("za") __arm_streaming {
|
||||
// for Lower Trangular Matrix
|
||||
uint64_t svl = svcntw();
|
||||
uint64_t col_batch = svl;
|
||||
|
||||
svzero_za();
|
||||
uint64_t last_rows_index = rows_index + rows - 1;
|
||||
for (uint64_t k = 0; k < cols; k += col_batch) {
|
||||
if (last_rows_index < k) {
|
||||
// Early exit: if all rows are above the diagonal, no valid elements remain
|
||||
break;
|
||||
}
|
||||
// Load to horizontal slices
|
||||
for (uint64_t row = 0; row < rows; row++) {
|
||||
svbool_t pg_row = svwhilelt_b32_u64(k, MIN(rows_index + row + 1, cols));
|
||||
svld1_hor_za32(0, row, pg_row, &a[row * a_step + k]);
|
||||
}
|
||||
|
||||
// Save from vertical slices
|
||||
col_batch = MIN(col_batch, cols - k);
|
||||
for (uint64_t col = 0; col < col_batch; col++) {
|
||||
svst1_ver_za32(0, col, svptrue_b32(), &b[(col + k) * svl]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
inline static void transpose_panel_upper(const float *restrict a, float *restrict b,
|
||||
uint64_t rows, uint64_t cols,
|
||||
uint64_t a_step, uint64_t rows_index)
|
||||
__arm_out("za") __arm_streaming {
|
||||
// for Upper Trangular Matrix
|
||||
uint64_t svl = svcntw();
|
||||
uint64_t col_batch = svl;
|
||||
|
||||
svzero_za();
|
||||
// Start from column k = rows_index to ensure we only process the upper triangle (k >= rows_index)
|
||||
for (uint64_t k = rows_index; k < cols; k += col_batch) {
|
||||
// Load to horizontal slices
|
||||
for (uint64_t row = 0; row < rows; row++) {
|
||||
svbool_t pg_row = svwhilelt_b32_u64(k, cols);
|
||||
svld1_hor_za32(0, row, pg_row, &a[row * a_step + k]);
|
||||
}
|
||||
|
||||
// Save from vertical slices
|
||||
col_batch = MIN(col_batch, cols - k);
|
||||
for (uint64_t col = 0, real_col = k; col < col_batch; col++, real_col++) {
|
||||
// Only the upper triangular part of the matrix is stored.
|
||||
svbool_t pg_col = svwhilelt_b32_u64(rows_index, real_col + 1);
|
||||
svst1_ver_za32(0, col, pg_col, &b[(col + k) * svl]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__arm_new("za") __arm_locally_streaming
|
||||
static void strmm_direct_sme1_preprocess(uint64_t nbr, uint64_t nbc,
|
||||
const float *restrict a, float *restrict a_mod) {
|
||||
const uint64_t num_rows = nbr;
|
||||
uint64_t row_batch = svcntsw();
|
||||
for (uint64_t row_idx = 0; row_idx < num_rows; row_idx += row_batch) {
|
||||
// Transpose 1SVL x N panel of A
|
||||
row_batch = MIN(row_batch, num_rows - row_idx);
|
||||
#if !defined(UPPER)
|
||||
transpose_panel_lower(&a[row_idx * nbc], &a_mod[row_idx * nbc], row_batch, nbc, nbc, row_idx);
|
||||
#else
|
||||
transpose_panel_upper(&a[row_idx * nbc], &a_mod[row_idx * nbc], row_batch, nbc, nbc, row_idx);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Outer product kernel.
|
||||
// Computes a 2SVL x 2SVL block of C, utilizing all four FP32 tiles of ZA.
|
||||
__attribute__((always_inline)) inline void
|
||||
kernel_2x2(const float *A, const float *B, float *C, size_t shared_dim,
|
||||
size_t ldc, size_t block_rows, size_t block_cols, float alpha, uint64_t row_idx)
|
||||
__arm_out("za") __arm_streaming {
|
||||
const uint64_t svl = svcntw();
|
||||
size_t ldb = ldc;
|
||||
// Predicate set-up
|
||||
svbool_t pg = svptrue_b32();
|
||||
svbool_t pg_a_0 = svwhilelt_b32_u64(0, block_rows);
|
||||
svbool_t pg_a_1 = svwhilelt_b32_u64(svl, block_rows);
|
||||
|
||||
#if (!defined(TRANSA) && !defined(UPPER)) || (defined(TRANSA) && defined(UPPER))
|
||||
#define pg_a_0_full pg_a_0
|
||||
#define pg_a_1_full pg_a_1
|
||||
#endif
|
||||
svbool_t pg_b_0 = svwhilelt_b32_u64(0, block_cols);
|
||||
svbool_t pg_b_1 = svwhilelt_b32_u64(svl, block_cols);
|
||||
|
||||
#define pg_c_0 pg_b_0
|
||||
#define pg_c_1 pg_b_1
|
||||
|
||||
svzero_za();
|
||||
svfloat32_t alpha_vec = svdup_f32(alpha);
|
||||
// Iterate through shared dimension (K)
|
||||
#if (!defined(TRANSA) && defined(UPPER)) || (defined(TRANSA) && !defined(UPPER))
|
||||
for (size_t k = row_idx, valid_index = 1; k < shared_dim; k++,valid_index++) {
|
||||
pg_a_0 = svwhilelt_b32_u64(0, MIN(valid_index, block_rows));
|
||||
pg_a_1 = svwhilelt_b32_u64(svl, MIN(valid_index, block_rows));
|
||||
#else
|
||||
for (size_t k = 0; k < MIN(row_idx + block_rows, shared_dim); k++) {
|
||||
// If k exceeds row_idx, mask out rows before (k - row_idx)
|
||||
// This ensures only valid rows are included for lower triangular logic.
|
||||
if (k > row_idx) {
|
||||
pg_a_0 = svnot_b_z(pg_a_0_full, svwhilelt_b32_u64(0, k - row_idx));
|
||||
pg_a_1 = svnot_b_z(pg_a_1_full, svwhilelt_b32_u64(svl, k - row_idx));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(TRANSA)
|
||||
// Load column of A
|
||||
svfloat32_t col_a_0 = svld1(pg_a_0, &A[k * svl]);
|
||||
svfloat32_t col_a_1 = svld1(pg_a_1, &A[(k + shared_dim) * svl]);
|
||||
#else
|
||||
svfloat32_t col_a_0 = svld1(pg_a_0, &A[k * shared_dim]);
|
||||
svfloat32_t col_a_1 = svld1(pg_a_1, &A[k * shared_dim + svl]);
|
||||
#endif
|
||||
col_a_0 = svmul_x(pg_a_0, alpha_vec, col_a_0);
|
||||
col_a_1 = svmul_x(pg_a_1, alpha_vec, col_a_1);
|
||||
// Load row of B
|
||||
svfloat32_t row_b_0 = svld1(pg_b_0, &B[k * ldb]);
|
||||
svfloat32_t row_b_1 = svld1(pg_b_1, &B[k * ldb + svl]);
|
||||
// Perform outer product
|
||||
svmopa_za32_m(/*tile*/0, pg_a_0, pg, col_a_0, row_b_0);
|
||||
svmopa_za32_m(/*tile*/1, pg_a_0, pg, col_a_0, row_b_1);
|
||||
svmopa_za32_m(/*tile*/2, pg_a_1, pg, col_a_1, row_b_0);
|
||||
svmopa_za32_m(/*tile*/3, pg_a_1, pg, col_a_1, row_b_1);
|
||||
}
|
||||
|
||||
// Store to C from ZA
|
||||
for (size_t i = 0; i < MIN(svl, block_rows); i++) {
|
||||
svst1_hor_za32(/*tile*/0, /*slice*/i, pg_c_0, &C[i * ldc]);
|
||||
svst1_hor_za32(/*tile*/1, /*slice*/i, pg_c_1, &C[i * ldc + svl]);
|
||||
}
|
||||
for (size_t i = svl; i < block_rows; i++) {
|
||||
svst1_hor_za32(/*tile*/2, /*slice*/i, pg_c_0, &C[i * ldc]);
|
||||
svst1_hor_za32(/*tile*/3, /*slice*/i, pg_c_1, &C[i * ldc + svl]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
__arm_new("za") __arm_locally_streaming
|
||||
static inline void strmm_direct_alpha_sme1_2VLx2VL(uint64_t m, uint64_t k, uint64_t n, const float* alpha,\
|
||||
const float *ba, float *restrict bb) {
|
||||
const uint64_t num_rows = m;
|
||||
const uint64_t num_cols = n;
|
||||
|
||||
const float *restrict a_ptr = ba;
|
||||
const float *restrict b_ptr = bb;
|
||||
float *restrict c_ptr = bb;
|
||||
|
||||
const uint64_t svl = svcntw();
|
||||
const uint64_t svl_x2 = 2*svl;
|
||||
const uint64_t ldc = n;
|
||||
|
||||
|
||||
uint64_t row_idx = 0;
|
||||
#if (!defined(TRANSA) && defined(UPPER)) || (defined(TRANSA) && !defined(UPPER))
|
||||
// 2x2 loop
|
||||
uint64_t row_batch = svl_x2;
|
||||
// Block over rows of C (panels of A)
|
||||
for (; row_idx < num_rows; row_idx += row_batch) {
|
||||
row_batch = MIN(row_batch, num_rows - row_idx);
|
||||
#else
|
||||
// Calculate the remainder of num_rows divided by 2VL to determine tail tile size
|
||||
uint64_t row_batch = num_rows % svl_x2;
|
||||
// If there's no remainder, use full tile size (2VL) for initial batch
|
||||
if (row_batch == 0) row_batch = svl_x2;
|
||||
// Loop from bottom to top, processing rows in batches
|
||||
for (uint64_t index = num_rows; index > 0; index -= row_batch, row_batch = svl_x2) {
|
||||
// Compute the starting row index for the current batch
|
||||
row_idx = index - row_batch;
|
||||
#endif
|
||||
uint64_t col_idx = 0;
|
||||
uint64_t col_batch = svl_x2;
|
||||
// Block over column dimension of C
|
||||
for (; col_idx < num_cols; col_idx += col_batch) {
|
||||
col_batch = MIN(col_batch, num_cols - col_idx);
|
||||
#if !defined(TRANSA)
|
||||
kernel_2x2(&a_ptr[row_idx * k], &b_ptr[col_idx],
|
||||
&c_ptr[row_idx * ldc + col_idx], k,
|
||||
ldc, row_batch, col_batch, *alpha, row_idx);
|
||||
#else
|
||||
kernel_2x2(&a_ptr[row_idx], &b_ptr[col_idx],
|
||||
&c_ptr[row_idx * ldc + col_idx], k,
|
||||
ldc, row_batch, col_batch, *alpha, row_idx);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
static void strmm_direct_sme1_preprocess(uint64_t nbr, uint64_t nbc,
|
||||
const float *restrict a, float *restrict a_mod) {}
|
||||
static void strmm_direct_alpha_sme1_2VLx2VL(uint64_t m, uint64_t k, uint64_t n, const float* alpha,\
|
||||
const float *ba, float *restrict bb){}
|
||||
#endif
|
||||
|
||||
void CNAME (BLASLONG M, BLASLONG N, float alpha, float * __restrict A,\
|
||||
BLASLONG strideA, float * __restrict B, BLASLONG strideB){
|
||||
#if !defined(TRANSA)
|
||||
uint64_t m_mod, vl_elms;
|
||||
|
||||
vl_elms = sve_cntw();
|
||||
|
||||
m_mod = ceil((double)M/(double)vl_elms) * vl_elms;
|
||||
|
||||
float *A_mod = (float *) malloc(m_mod*M*sizeof(float));
|
||||
strmm_direct_sme1_preprocess(M, M, A, A_mod);
|
||||
/* Calculate B = alpha*A*B*/
|
||||
strmm_direct_alpha_sme1_2VLx2VL(M, M, N, &alpha, A_mod, B);
|
||||
free(A_mod);
|
||||
#else
|
||||
strmm_direct_alpha_sme1_2VLx2VL(M, M, N, &alpha, A, B);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
void CNAME (BLASLONG M, BLASLONG N, float alpha, float * __restrict A,\
|
||||
BLASLONG strideA, float * __restrict B, BLASLONG strideB){
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -32,7 +32,9 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <complex.h>
|
||||
#endif
|
||||
#include <arm_neon.h>
|
||||
|
||||
#define N "x0" /* vector length */
|
||||
@@ -197,14 +199,20 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#if defined(SMP)
|
||||
extern int blas_level1_thread_with_return_value(int mode, BLASLONG m, BLASLONG n,
|
||||
BLASLONG k, void *alpha, void *a, BLASLONG lda, void *b, BLASLONG ldb,
|
||||
void *c, BLASLONG ldc, int (*function)(), int nthreads);
|
||||
void *c, BLASLONG ldc, int (*function)(void), int nthreads);
|
||||
#endif
|
||||
|
||||
static void zdot_compute(BLASLONG n, FLOAT *x, BLASLONG inc_x, FLOAT *y, BLASLONG inc_y, OPENBLAS_COMPLEX_FLOAT *result)
|
||||
{
|
||||
FLOAT dotr = 0.0, doti = 0.0;
|
||||
FLOAT dotr = 0.0, doti = 0.0;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
CREAL(*result) = 0.0;
|
||||
CIMAG(*result) = 0.0;
|
||||
#else
|
||||
OPENBLAS_COMPLEX_FLOAT cf = OPENBLAS_MAKE_COMPLEX_FLOAT(0.0, 0.0);
|
||||
*result = cf;
|
||||
*result = cf;
|
||||
#endif
|
||||
|
||||
if ( n < 0 ) return;
|
||||
|
||||
@@ -235,8 +243,9 @@ static void zdot_compute(BLASLONG n, FLOAT *x, BLASLONG inc_x, FLOAT *y, BLASLON
|
||||
" asr "J", "N", #"N_DIV_SHIFT" \n"
|
||||
" cmp "J", xzr \n"
|
||||
" beq 3f //dot_kernel_F1 \n"
|
||||
|
||||
#ifndef _MSC_VER
|
||||
" .align 5 \n"
|
||||
#endif
|
||||
"2: //dot_kernel_F: \n"
|
||||
" "KERNEL_F" \n"
|
||||
" subs "J", "J", #1 \n"
|
||||
@@ -297,10 +306,14 @@ static void zdot_compute(BLASLONG n, FLOAT *x, BLASLONG inc_x, FLOAT *y, BLASLON
|
||||
"v23", "v24", "v25", "v26", "v27", "v28", "v29",
|
||||
"v30", "v31"
|
||||
);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
CREAL(*result) = dotr;
|
||||
CIMAG(*result) = doti;
|
||||
#else
|
||||
cf=OPENBLAS_MAKE_COMPLEX_FLOAT(dotr, doti);
|
||||
*result = cf;
|
||||
return;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(SMP)
|
||||
@@ -320,7 +333,13 @@ OPENBLAS_COMPLEX_FLOAT CNAME(BLASLONG n, FLOAT *x, BLASLONG inc_x, FLOAT *y, BLA
|
||||
int nthreads;
|
||||
FLOAT dummy_alpha;
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
OPENBLAS_COMPLEX_FLOAT zdot;
|
||||
CREAL(zdot) = 0.0;
|
||||
CIMAG(zdot) = 0.0;
|
||||
#else
|
||||
OPENBLAS_COMPLEX_FLOAT zdot = OPENBLAS_MAKE_COMPLEX_FLOAT(0.0,0.0);
|
||||
#endif
|
||||
|
||||
#if defined(SMP)
|
||||
if (inc_x == 0 || inc_y == 0 || n <= 10000)
|
||||
@@ -347,7 +366,11 @@ OPENBLAS_COMPLEX_FLOAT CNAME(BLASLONG n, FLOAT *x, BLASLONG inc_x, FLOAT *y, BLA
|
||||
|
||||
ptr = (OPENBLAS_COMPLEX_FLOAT *)result;
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
#ifdef _MSC_VER
|
||||
CREAL(zdot)+= CREAL(*ptr);CIMAG(zdot)+=CIMAG(*ptr);
|
||||
#else
|
||||
zdot = OPENBLAS_MAKE_COMPLEX_FLOAT (CREAL(zdot) + CREAL(*ptr), CIMAG(zdot) + CIMAG(*ptr));
|
||||
#endif
|
||||
ptr = (void *)(((char *)ptr) + sizeof(double) * 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
* *****************************************************************************/
|
||||
|
||||
#if defined(BFLOAT16) && defined(BFLOAT16CONVERSION)
|
||||
|
||||
static float
|
||||
bfloat16tof32 (bfloat16 value)
|
||||
{
|
||||
@@ -48,17 +49,34 @@ static bfloat16 f32tobfloat16(float value) {
|
||||
#ifdef BGEMM
|
||||
#define ALPHA bfloat16tof32(alpha)
|
||||
#define BETA bfloat16tof32(beta)
|
||||
#define BF16TOF32(x) (bfloat16tof32(x))
|
||||
#define F32TOBF16(x) (f32tobfloat16(x))
|
||||
#define TO_F32(x) (bfloat16tof32(x))
|
||||
#define TO_OUTPUT(x) (f32tobfloat16(x))
|
||||
#else
|
||||
#define ALPHA alpha
|
||||
#define BETA beta
|
||||
#define BF16TOF32(x) (bfloat16tof32(x))
|
||||
#define F32TOBF16(x) x
|
||||
#define TO_F32(x) (bfloat16tof32(x))
|
||||
#define TO_OUTPUT(x) x
|
||||
#endif
|
||||
|
||||
#elif defined(HFLOAT16)
|
||||
|
||||
#ifdef HGEMM
|
||||
#define ALPHA (float)(alpha)
|
||||
#define BETA (float)(beta)
|
||||
#define TO_F32(x) ((float)(x))
|
||||
#define TO_OUTPUT(x) ((_Float16)(x))
|
||||
#else
|
||||
#define ALPHA alpha
|
||||
#define BETA beta
|
||||
#define BF16TOF32(x) x
|
||||
#define F32TOBF16(x) x
|
||||
#define TO_F32(x) ((float)(x))
|
||||
#define TO_OUTPUT(x) x
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define ALPHA alpha
|
||||
#define BETA beta
|
||||
#define TO_F32(x) x
|
||||
#define TO_OUTPUT(x) x
|
||||
|
||||
#endif
|
||||
@@ -27,7 +27,8 @@
|
||||
* *****************************************************************************/
|
||||
|
||||
#include "common.h"
|
||||
#include "bf16_macros.h"
|
||||
|
||||
#include "conversion_macros.h"
|
||||
|
||||
int CNAME(BLASLONG bm,BLASLONG bn,BLASLONG bk,FLOAT alpha,IFLOAT* ba,IFLOAT* bb,FLOAT* C,BLASLONG ldc
|
||||
#ifdef TRMMKERNEL
|
||||
@@ -60,36 +61,36 @@ int CNAME(BLASLONG bm,BLASLONG bn,BLASLONG bk,FLOAT alpha,IFLOAT* ba,IFLOAT* bb,
|
||||
{
|
||||
load0 = ptrba[2*0+0];
|
||||
load1 = ptrbb[2*0+0];
|
||||
res0 = res0+BF16TOF32(load0)*BF16TOF32(load1);
|
||||
res0 = res0+TO_F32(load0)*TO_F32(load1);
|
||||
load2 = ptrba[2*0+1];
|
||||
res1 = res1+BF16TOF32(load2)*BF16TOF32(load1);
|
||||
res1 = res1+TO_F32(load2)*TO_F32(load1);
|
||||
load3 = ptrbb[2*0+1];
|
||||
res2 = res2+BF16TOF32(load0)*BF16TOF32(load3);
|
||||
res3 = res3+BF16TOF32(load2)*BF16TOF32(load3);
|
||||
res2 = res2+TO_F32(load0)*TO_F32(load3);
|
||||
res3 = res3+TO_F32(load2)*TO_F32(load3);
|
||||
load4 = ptrba[2*1+0];
|
||||
load5 = ptrbb[2*1+0];
|
||||
res0 = res0+BF16TOF32(load4)*BF16TOF32(load5);
|
||||
res0 = res0+TO_F32(load4)*TO_F32(load5);
|
||||
load6 = ptrba[2*1+1];
|
||||
res1 = res1+BF16TOF32(load6)*BF16TOF32(load5);
|
||||
res1 = res1+TO_F32(load6)*TO_F32(load5);
|
||||
load7 = ptrbb[2*1+1];
|
||||
res2 = res2+BF16TOF32(load4)*BF16TOF32(load7);
|
||||
res3 = res3+BF16TOF32(load6)*BF16TOF32(load7);
|
||||
res2 = res2+TO_F32(load4)*TO_F32(load7);
|
||||
res3 = res3+TO_F32(load6)*TO_F32(load7);
|
||||
load0 = ptrba[2*2+0];
|
||||
load1 = ptrbb[2*2+0];
|
||||
res0 = res0+BF16TOF32(load0)*BF16TOF32(load1);
|
||||
res0 = res0+TO_F32(load0)*TO_F32(load1);
|
||||
load2 = ptrba[2*2+1];
|
||||
res1 = res1+BF16TOF32(load2)*BF16TOF32(load1);
|
||||
res1 = res1+TO_F32(load2)*TO_F32(load1);
|
||||
load3 = ptrbb[2*2+1];
|
||||
res2 = res2+BF16TOF32(load0)*BF16TOF32(load3);
|
||||
res3 = res3+BF16TOF32(load2)*BF16TOF32(load3);
|
||||
res2 = res2+TO_F32(load0)*TO_F32(load3);
|
||||
res3 = res3+TO_F32(load2)*TO_F32(load3);
|
||||
load4 = ptrba[2*3+0];
|
||||
load5 = ptrbb[2*3+0];
|
||||
res0 = res0+BF16TOF32(load4)*BF16TOF32(load5);
|
||||
res0 = res0+TO_F32(load4)*TO_F32(load5);
|
||||
load6 = ptrba[2*3+1];
|
||||
res1 = res1+BF16TOF32(load6)*BF16TOF32(load5);
|
||||
res1 = res1+TO_F32(load6)*TO_F32(load5);
|
||||
load7 = ptrbb[2*3+1];
|
||||
res2 = res2+BF16TOF32(load4)*BF16TOF32(load7);
|
||||
res3 = res3+BF16TOF32(load6)*BF16TOF32(load7);
|
||||
res2 = res2+TO_F32(load4)*TO_F32(load7);
|
||||
res3 = res3+TO_F32(load6)*TO_F32(load7);
|
||||
ptrba = ptrba+8;
|
||||
ptrbb = ptrbb+8;
|
||||
}
|
||||
@@ -97,23 +98,23 @@ int CNAME(BLASLONG bm,BLASLONG bn,BLASLONG bk,FLOAT alpha,IFLOAT* ba,IFLOAT* bb,
|
||||
{
|
||||
load0 = ptrba[2*0+0];
|
||||
load1 = ptrbb[2*0+0];
|
||||
res0 = res0+BF16TOF32(load0)*BF16TOF32(load1);
|
||||
res0 = res0+TO_F32(load0)*TO_F32(load1);
|
||||
load2 = ptrba[2*0+1];
|
||||
res1 = res1+BF16TOF32(load2)*BF16TOF32(load1);
|
||||
res1 = res1+TO_F32(load2)*TO_F32(load1);
|
||||
load3 = ptrbb[2*0+1];
|
||||
res2 = res2+BF16TOF32(load0)*BF16TOF32(load3);
|
||||
res3 = res3+BF16TOF32(load2)*BF16TOF32(load3);
|
||||
res2 = res2+TO_F32(load0)*TO_F32(load3);
|
||||
res3 = res3+TO_F32(load2)*TO_F32(load3);
|
||||
ptrba = ptrba+2;
|
||||
ptrbb = ptrbb+2;
|
||||
}
|
||||
res0 = res0*ALPHA;
|
||||
C0[0] = F32TOBF16(BF16TOF32(C0[0])+res0);
|
||||
C0[0] = TO_OUTPUT(TO_F32(C0[0])+res0);
|
||||
res1 = res1*ALPHA;
|
||||
C0[1] = F32TOBF16(BF16TOF32(C0[1])+res1);
|
||||
C0[1] = TO_OUTPUT(TO_F32(C0[1])+res1);
|
||||
res2 = res2*ALPHA;
|
||||
C1[0] = F32TOBF16(BF16TOF32(C1[0])+res2);
|
||||
C1[0] = TO_OUTPUT(TO_F32(C1[0])+res2);
|
||||
res3 = res3*ALPHA;
|
||||
C1[1] = F32TOBF16(BF16TOF32(C1[1])+res3);
|
||||
C1[1] = TO_OUTPUT(TO_F32(C1[1])+res3);
|
||||
C0 = C0+2;
|
||||
C1 = C1+2;
|
||||
}
|
||||
@@ -126,16 +127,16 @@ int CNAME(BLASLONG bm,BLASLONG bn,BLASLONG bk,FLOAT alpha,IFLOAT* ba,IFLOAT* bb,
|
||||
{
|
||||
load0 = ptrba[0+0];
|
||||
load1 = ptrbb[2*0+0];
|
||||
res0 = res0+BF16TOF32(load0)*BF16TOF32(load1);
|
||||
res0 = res0+TO_F32(load0)*TO_F32(load1);
|
||||
load2 = ptrbb[2*0+1];
|
||||
res1 = res1+BF16TOF32(load0)*BF16TOF32(load2);
|
||||
res1 = res1+TO_F32(load0)*TO_F32(load2);
|
||||
ptrba = ptrba+1;
|
||||
ptrbb = ptrbb+2;
|
||||
}
|
||||
res0 = res0*ALPHA;
|
||||
C0[0] = F32TOBF16(BF16TOF32(C0[0])+res0);
|
||||
C0[0] = TO_OUTPUT(TO_F32(C0[0])+res0);
|
||||
res1 = res1*ALPHA;
|
||||
C1[0] = F32TOBF16(BF16TOF32(C1[0])+res1);
|
||||
C1[0] = TO_OUTPUT(TO_F32(C1[0])+res1);
|
||||
C0 = C0+1;
|
||||
C1 = C1+1;
|
||||
}
|
||||
@@ -157,16 +158,16 @@ int CNAME(BLASLONG bm,BLASLONG bn,BLASLONG bk,FLOAT alpha,IFLOAT* ba,IFLOAT* bb,
|
||||
{
|
||||
load0 = ptrba[2*0+0];
|
||||
load1 = ptrbb[0+0];
|
||||
res0 = res0+BF16TOF32(load0)*BF16TOF32(load1);
|
||||
res0 = res0+TO_F32(load0)*TO_F32(load1);
|
||||
load2 = ptrba[2*0+1];
|
||||
res1 = res1+BF16TOF32(load2)*BF16TOF32(load1);
|
||||
res1 = res1+TO_F32(load2)*TO_F32(load1);
|
||||
ptrba = ptrba+2;
|
||||
ptrbb = ptrbb+1;
|
||||
}
|
||||
res0 = res0*ALPHA;
|
||||
C0[0] = F32TOBF16(BF16TOF32(C0[0])+res0);
|
||||
C0[0] = TO_OUTPUT(TO_F32(C0[0])+res0);
|
||||
res1 = res1*ALPHA;
|
||||
C0[1] = F32TOBF16(BF16TOF32(C0[1])+res1);
|
||||
C0[1] = TO_OUTPUT(TO_F32(C0[1])+res1);
|
||||
C0 = C0+2;
|
||||
}
|
||||
for (i=0; i<(bm&1); i+=1)
|
||||
@@ -177,12 +178,12 @@ int CNAME(BLASLONG bm,BLASLONG bn,BLASLONG bk,FLOAT alpha,IFLOAT* ba,IFLOAT* bb,
|
||||
{
|
||||
load0 = ptrba[0+0];
|
||||
load1 = ptrbb[0+0];
|
||||
res0 = res0+BF16TOF32(load0)*BF16TOF32(load1);
|
||||
res0 = res0+TO_F32(load0)*TO_F32(load1);
|
||||
ptrba = ptrba+1;
|
||||
ptrbb = ptrbb+1;
|
||||
}
|
||||
res0 = res0*ALPHA;
|
||||
C0[0] = F32TOBF16(BF16TOF32(C0[0])+res0);
|
||||
C0[0] = TO_OUTPUT(TO_F32(C0[0])+res0);
|
||||
C0 = C0+1;
|
||||
}
|
||||
k = (bk<<0);
|
||||
|
||||
@@ -26,15 +26,14 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "common.h"
|
||||
#include "bf16_macros.h"
|
||||
|
||||
#include "conversion_macros.h"
|
||||
|
||||
int CNAME(BLASLONG m, BLASLONG n, FLOAT alpha, IFLOAT *a, BLASLONG lda, IFLOAT *x, BLASLONG inc_x, FLOAT beta, FLOAT *y, BLASLONG inc_y)
|
||||
{
|
||||
BLASLONG i;
|
||||
BLASLONG ix, iy;
|
||||
BLASLONG j;
|
||||
FLOAT *a_ptr;
|
||||
#ifdef BGEMM
|
||||
IFLOAT *a_ptr;
|
||||
#if defined(BGEMM) || defined(HGEMM)
|
||||
float temp;
|
||||
#else
|
||||
FLOAT temp;
|
||||
@@ -49,18 +48,18 @@ int CNAME(BLASLONG m, BLASLONG n, FLOAT alpha, IFLOAT *a, BLASLONG lda, IFLOAT *
|
||||
a_ptr = a;
|
||||
for (BLASLONG j = 0; j < n; j++)
|
||||
{
|
||||
temp += BF16TOF32(a_ptr[i]) * BF16TOF32(x[ix]);
|
||||
temp += TO_F32(a_ptr[i]) * TO_F32(x[ix]);
|
||||
ix += inc_x;
|
||||
a_ptr += lda;
|
||||
}
|
||||
|
||||
if (BETA == ZERO)
|
||||
{
|
||||
y[iy] = F32TOBF16(ALPHA * temp);
|
||||
y[iy] = TO_OUTPUT(ALPHA * temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
y[iy] = F32TOBF16(ALPHA * temp + BETA * BF16TOF32(y[iy]));
|
||||
y[iy] = TO_OUTPUT(ALPHA * temp + BETA * TO_F32(y[iy]));
|
||||
}
|
||||
|
||||
iy += inc_y;
|
||||
|
||||
+13
-5
@@ -26,15 +26,16 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "common.h"
|
||||
#include "bf16_macros.h"
|
||||
|
||||
#include "conversion_macros.h"
|
||||
|
||||
int CNAME(BLASLONG m, BLASLONG n, FLOAT alpha, IFLOAT *a, BLASLONG lda, IFLOAT *x, BLASLONG inc_x, FLOAT beta, FLOAT *y, BLASLONG inc_y)
|
||||
{
|
||||
BLASLONG i;
|
||||
BLASLONG ix, iy;
|
||||
BLASLONG j;
|
||||
FLOAT *a_ptr;
|
||||
#ifdef BGEMM
|
||||
IFLOAT *a_ptr;
|
||||
#if defined(BGEMM) || defined(HGEMM)
|
||||
float temp;
|
||||
#else
|
||||
FLOAT temp;
|
||||
@@ -49,10 +50,17 @@ int CNAME(BLASLONG m, BLASLONG n, FLOAT alpha, IFLOAT *a, BLASLONG lda, IFLOAT *
|
||||
ix = 0;
|
||||
for (i = 0; i < m; i++)
|
||||
{
|
||||
temp += BF16TOF32(a_ptr[i]) * BF16TOF32(x[ix]);
|
||||
temp += TO_F32(a_ptr[i]) * TO_F32(x[ix]);
|
||||
ix += inc_x;
|
||||
}
|
||||
y[iy] += F32TOBF16(ALPHA * temp);
|
||||
if (BETA == ZERO)
|
||||
{
|
||||
y[iy] = TO_OUTPUT(ALPHA * temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
y[iy] = TO_OUTPUT(ALPHA * temp + BETA * TO_F32(y[iy]));
|
||||
}
|
||||
iy += inc_y;
|
||||
a_ptr += lda;
|
||||
}
|
||||
|
||||
@@ -212,15 +212,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
SDARG $r25, $sp, 16
|
||||
SDARG $r26, $sp, 24
|
||||
SDARG $r27, $sp, 32
|
||||
ST $f23, $sp, 40
|
||||
ST $f24, $sp, 48
|
||||
ST $f25, $sp, 56
|
||||
ST $f26, $sp, 64
|
||||
ST $f27, $sp, 72
|
||||
ST $f28, $sp, 80
|
||||
ST $f29, $sp, 88
|
||||
ST $f30, $sp, 96
|
||||
ST $f31, $sp, 104
|
||||
fst.d $f23, $sp, 40
|
||||
fst.d $f24, $sp, 48
|
||||
fst.d $f25, $sp, 56
|
||||
fst.d $f26, $sp, 64
|
||||
fst.d $f27, $sp, 72
|
||||
fst.d $f28, $sp, 80
|
||||
fst.d $f29, $sp, 88
|
||||
fst.d $f30, $sp, 96
|
||||
fst.d $f31, $sp, 104
|
||||
ST ALPHA_R,$sp, 112
|
||||
ST ALPHA_I,$sp, 120
|
||||
|
||||
@@ -841,15 +841,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
LDARG $r25, $sp, 16
|
||||
LDARG $r26, $sp, 24
|
||||
LDARG $r27, $sp, 32
|
||||
LD $f23, $sp, 40
|
||||
LD $f24, $sp, 48
|
||||
LD $f25, $sp, 56
|
||||
LD $f26, $sp, 64
|
||||
LD $f27, $sp, 72
|
||||
LD $f28, $sp, 80
|
||||
LD $f29, $sp, 88
|
||||
LD $f30, $sp, 96
|
||||
LD $f31, $sp, 104
|
||||
fld.d $f23, $sp, 40
|
||||
fld.d $f24, $sp, 48
|
||||
fld.d $f25, $sp, 56
|
||||
fld.d $f26, $sp, 64
|
||||
fld.d $f27, $sp, 72
|
||||
fld.d $f28, $sp, 80
|
||||
fld.d $f29, $sp, 88
|
||||
fld.d $f30, $sp, 96
|
||||
fld.d $f31, $sp, 104
|
||||
|
||||
addi.d $sp, $sp, 128
|
||||
jirl $r0, $r1, 0x0
|
||||
|
||||
@@ -172,15 +172,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
SDARG $r25, $sp, 16
|
||||
SDARG $r26, $sp, 24
|
||||
SDARG $r27, $sp, 32
|
||||
ST $f23, $sp, 40
|
||||
ST $f24, $sp, 48
|
||||
ST $f25, $sp, 56
|
||||
ST $f26, $sp, 64
|
||||
ST $f27, $sp, 72
|
||||
ST $f28, $sp, 80
|
||||
ST $f29, $sp, 88
|
||||
ST $f30, $sp, 96
|
||||
ST $f31, $sp, 104
|
||||
fst.d $f23, $sp, 40
|
||||
fst.d $f24, $sp, 48
|
||||
fst.d $f25, $sp, 56
|
||||
fst.d $f26, $sp, 64
|
||||
fst.d $f27, $sp, 72
|
||||
fst.d $f28, $sp, 80
|
||||
fst.d $f29, $sp, 88
|
||||
fst.d $f30, $sp, 96
|
||||
fst.d $f31, $sp, 104
|
||||
ST ALPHA_R,$sp, 112
|
||||
ST ALPHA_I,$sp, 120
|
||||
|
||||
@@ -796,15 +796,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
LDARG $r25, $sp, 16
|
||||
LDARG $r26, $sp, 24
|
||||
LDARG $r27, $sp, 32
|
||||
LD $f23, $sp, 40
|
||||
LD $f24, $sp, 48
|
||||
LD $f25, $sp, 56
|
||||
LD $f26, $sp, 64
|
||||
LD $f27, $sp, 72
|
||||
LD $f28, $sp, 80
|
||||
LD $f29, $sp, 88
|
||||
LD $f30, $sp, 96
|
||||
LD $f31, $sp, 104
|
||||
fld.d $f23, $sp, 40
|
||||
fld.d $f24, $sp, 48
|
||||
fld.d $f25, $sp, 56
|
||||
fld.d $f26, $sp, 64
|
||||
fld.d $f27, $sp, 72
|
||||
fld.d $f28, $sp, 80
|
||||
fld.d $f29, $sp, 88
|
||||
fld.d $f30, $sp, 96
|
||||
fld.d $f31, $sp, 104
|
||||
|
||||
addi.d $sp, $sp, 128
|
||||
jirl $r0, $r1, 0x0
|
||||
|
||||
@@ -176,15 +176,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
SDARG $r25, $sp, 16
|
||||
SDARG $r26, $sp, 24
|
||||
SDARG $r27, $sp, 32
|
||||
ST $f23, $sp, 40
|
||||
ST $f24, $sp, 48
|
||||
ST $f25, $sp, 56
|
||||
ST $f26, $sp, 64
|
||||
ST $f27, $sp, 72
|
||||
ST $f28, $sp, 80
|
||||
ST $f29, $sp, 88
|
||||
ST $f30, $sp, 96
|
||||
ST $f31, $sp, 104
|
||||
fst.d $f23, $sp, 40
|
||||
fst.d $f24, $sp, 48
|
||||
fst.d $f25, $sp, 56
|
||||
fst.d $f26, $sp, 64
|
||||
fst.d $f27, $sp, 72
|
||||
fst.d $f28, $sp, 80
|
||||
fst.d $f29, $sp, 88
|
||||
fst.d $f30, $sp, 96
|
||||
fst.d $f31, $sp, 104
|
||||
ST ALPHA_R,$sp, 112
|
||||
ST ALPHA_I,$sp, 120
|
||||
|
||||
@@ -3297,15 +3297,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
LDARG $r25, $sp, 16
|
||||
LDARG $r26, $sp, 24
|
||||
LDARG $r27, $sp, 32
|
||||
LD $f23, $sp, 40
|
||||
LD $f24, $sp, 48
|
||||
LD $f25, $sp, 56
|
||||
LD $f26, $sp, 64
|
||||
LD $f27, $sp, 72
|
||||
LD $f28, $sp, 80
|
||||
LD $f29, $sp, 88
|
||||
LD $f30, $sp, 96
|
||||
LD $f31, $sp, 104
|
||||
fld.d $f23, $sp, 40
|
||||
fld.d $f24, $sp, 48
|
||||
fld.d $f25, $sp, 56
|
||||
fld.d $f26, $sp, 64
|
||||
fld.d $f27, $sp, 72
|
||||
fld.d $f28, $sp, 80
|
||||
fld.d $f29, $sp, 88
|
||||
fld.d $f30, $sp, 96
|
||||
fld.d $f31, $sp, 104
|
||||
|
||||
addi.d $sp, $sp, 128
|
||||
jirl $r0, $r1, 0x0
|
||||
|
||||
@@ -893,14 +893,14 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
SDARG $r25, $sp, 16
|
||||
SDARG $r26, $sp, 24
|
||||
SDARG $r27, $sp, 32
|
||||
ST $f24, $sp, 40
|
||||
ST $f25, $sp, 48
|
||||
ST $f26, $sp, 56
|
||||
ST $f27, $sp, 64
|
||||
ST $f28, $sp, 72
|
||||
ST $f29, $sp, 80
|
||||
ST $f30, $sp, 88
|
||||
ST $f31, $sp, 96
|
||||
fst.d $f24, $sp, 40
|
||||
fst.d $f25, $sp, 48
|
||||
fst.d $f26, $sp, 56
|
||||
fst.d $f27, $sp, 64
|
||||
fst.d $f28, $sp, 72
|
||||
fst.d $f29, $sp, 80
|
||||
fst.d $f30, $sp, 88
|
||||
fst.d $f31, $sp, 96
|
||||
ST ALPHA, $sp, 104
|
||||
|
||||
#if defined (TRMMKERNEL) && !defined(LEFT)
|
||||
@@ -2879,14 +2879,14 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
LDARG $r25, $sp, 16
|
||||
LDARG $r26, $sp, 24
|
||||
LDARG $r27, $sp, 32
|
||||
LD $f24, $sp, 40
|
||||
LD $f25, $sp, 48
|
||||
LD $f26, $sp, 56
|
||||
LD $f27, $sp, 64
|
||||
LD $f28, $sp, 72
|
||||
LD $f29, $sp, 80
|
||||
LD $f30, $sp, 88
|
||||
LD $f31, $sp, 96
|
||||
fld.d $f24, $sp, 40
|
||||
fld.d $f25, $sp, 48
|
||||
fld.d $f26, $sp, 56
|
||||
fld.d $f27, $sp, 64
|
||||
fld.d $f28, $sp, 72
|
||||
fld.d $f29, $sp, 80
|
||||
fld.d $f30, $sp, 88
|
||||
fld.d $f31, $sp, 96
|
||||
addi.d $sp, $sp, 112
|
||||
|
||||
jirl $r0, $r1, 0x0
|
||||
|
||||
@@ -113,15 +113,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
SDARG $r29, $sp, 0x30
|
||||
SDARG $r30, $sp, 0x38
|
||||
SDARG $r31, $sp, 0x40
|
||||
ST $f23, $sp, 0x48
|
||||
ST $f24, $sp, 0x50
|
||||
ST $f25, $sp, 0x58
|
||||
ST $f26, $sp, 0x60
|
||||
ST $f27, $sp, 0x68
|
||||
ST $f28, $sp, 0x70
|
||||
ST $f29, $sp, 0x78
|
||||
ST $f30, $sp, 0x80
|
||||
ST $f31, $sp, 0x88
|
||||
fst.d $f23, $sp, 0x48
|
||||
fst.d $f24, $sp, 0x50
|
||||
fst.d $f25, $sp, 0x58
|
||||
fst.d $f26, $sp, 0x60
|
||||
fst.d $f27, $sp, 0x68
|
||||
fst.d $f28, $sp, 0x70
|
||||
fst.d $f29, $sp, 0x78
|
||||
fst.d $f30, $sp, 0x80
|
||||
fst.d $f31, $sp, 0x88
|
||||
|
||||
move TD, DST
|
||||
move TS, SRC
|
||||
@@ -678,15 +678,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
LDARG $r29, $sp, 0x30
|
||||
LDARG $r30, $sp, 0x38
|
||||
LDARG $r31, $sp, 0x40
|
||||
LD $f23, $sp, 0x48
|
||||
LD $f24, $sp, 0x50
|
||||
LD $f25, $sp, 0x58
|
||||
LD $f26, $sp, 0x60
|
||||
LD $f27, $sp, 0x68
|
||||
LD $f28, $sp, 0x70
|
||||
LD $f29, $sp, 0x78
|
||||
LD $f30, $sp, 0x80
|
||||
LD $f31, $sp, 0x88
|
||||
fld.d $f23, $sp, 0x48
|
||||
fld.d $f24, $sp, 0x50
|
||||
fld.d $f25, $sp, 0x58
|
||||
fld.d $f26, $sp, 0x60
|
||||
fld.d $f27, $sp, 0x68
|
||||
fld.d $f28, $sp, 0x70
|
||||
fld.d $f29, $sp, 0x78
|
||||
fld.d $f30, $sp, 0x80
|
||||
fld.d $f31, $sp, 0x88
|
||||
addi.d $sp, $sp, 0x90
|
||||
jirl $r0, $r1, 0x00
|
||||
|
||||
|
||||
@@ -123,13 +123,13 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
SDARG $r24, $sp, 8
|
||||
SDARG $r25, $sp, 16
|
||||
SDARG $r26, $sp, 24
|
||||
ST $f23, $sp, 32
|
||||
ST $f24, $sp, 40
|
||||
ST $f25, $sp, 48
|
||||
ST $f26, $sp, 56
|
||||
ST $f27, $sp, 64
|
||||
ST $f28, $sp, 72
|
||||
ST $f29, $sp, 80
|
||||
fst.d $f23, $sp, 32
|
||||
fst.d $f24, $sp, 40
|
||||
fst.d $f25, $sp, 48
|
||||
fst.d $f26, $sp, 56
|
||||
fst.d $f27, $sp, 64
|
||||
fst.d $f28, $sp, 72
|
||||
fst.d $f29, $sp, 80
|
||||
|
||||
|
||||
#if defined (TRMMKERNEL) && !defined(LEFT)
|
||||
@@ -834,13 +834,13 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
LDARG $r24, $sp, 8
|
||||
LDARG $r25, $sp, 16
|
||||
LDARG $r26, $sp, 24
|
||||
LD $f23, $sp, 32
|
||||
LD $f24, $sp, 40
|
||||
LD $f25, $sp, 48
|
||||
LD $f26, $sp, 56
|
||||
LD $f27, $sp, 64
|
||||
LD $f28, $sp, 72
|
||||
LD $f29, $sp, 80
|
||||
fld.d $f23, $sp, 32
|
||||
fld.d $f24, $sp, 40
|
||||
fld.d $f25, $sp, 48
|
||||
fld.d $f26, $sp, 56
|
||||
fld.d $f27, $sp, 64
|
||||
fld.d $f28, $sp, 72
|
||||
fld.d $f29, $sp, 80
|
||||
|
||||
addi.d $sp, $sp, 88
|
||||
jirl $r0, $r1, 0x0
|
||||
|
||||
@@ -174,15 +174,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
SDARG $r25, $sp, 16
|
||||
SDARG $r26, $sp, 24
|
||||
SDARG $r27, $sp, 32
|
||||
ST $f23, $sp, 40
|
||||
ST $f24, $sp, 48
|
||||
ST $f25, $sp, 56
|
||||
ST $f26, $sp, 64
|
||||
ST $f27, $sp, 72
|
||||
ST $f28, $sp, 80
|
||||
ST $f29, $sp, 88
|
||||
ST $f30, $sp, 96
|
||||
ST $f31, $sp, 104
|
||||
fst.d $f23, $sp, 40
|
||||
fst.d $f24, $sp, 48
|
||||
fst.d $f25, $sp, 56
|
||||
fst.d $f26, $sp, 64
|
||||
fst.d $f27, $sp, 72
|
||||
fst.d $f28, $sp, 80
|
||||
fst.d $f29, $sp, 88
|
||||
fst.d $f30, $sp, 96
|
||||
fst.d $f31, $sp, 104
|
||||
ST ALPHA_R,$sp, 112
|
||||
ST ALPHA_I,$sp, 120
|
||||
|
||||
@@ -806,15 +806,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
LDARG $r25, $sp, 16
|
||||
LDARG $r26, $sp, 24
|
||||
LDARG $r27, $sp, 32
|
||||
LD $f23, $sp, 40
|
||||
LD $f24, $sp, 48
|
||||
LD $f25, $sp, 56
|
||||
LD $f26, $sp, 64
|
||||
LD $f27, $sp, 72
|
||||
LD $f28, $sp, 80
|
||||
LD $f29, $sp, 88
|
||||
LD $f30, $sp, 96
|
||||
LD $f31, $sp, 104
|
||||
fld.d $f23, $sp, 40
|
||||
fld.d $f24, $sp, 48
|
||||
fld.d $f25, $sp, 56
|
||||
fld.d $f26, $sp, 64
|
||||
fld.d $f27, $sp, 72
|
||||
fld.d $f28, $sp, 80
|
||||
fld.d $f29, $sp, 88
|
||||
fld.d $f30, $sp, 96
|
||||
fld.d $f31, $sp, 104
|
||||
|
||||
addi.d $sp, $sp, 128
|
||||
jirl $r0, $r1, 0x0
|
||||
|
||||
@@ -176,15 +176,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
SDARG $r25, $sp, 16
|
||||
SDARG $r26, $sp, 24
|
||||
SDARG $r27, $sp, 32
|
||||
ST $f23, $sp, 40
|
||||
ST $f24, $sp, 48
|
||||
ST $f25, $sp, 56
|
||||
ST $f26, $sp, 64
|
||||
ST $f27, $sp, 72
|
||||
ST $f28, $sp, 80
|
||||
ST $f29, $sp, 88
|
||||
ST $f30, $sp, 96
|
||||
ST $f31, $sp, 104
|
||||
fst.d $f23, $sp, 40
|
||||
fst.d $f24, $sp, 48
|
||||
fst.d $f25, $sp, 56
|
||||
fst.d $f26, $sp, 64
|
||||
fst.d $f27, $sp, 72
|
||||
fst.d $f28, $sp, 80
|
||||
fst.d $f29, $sp, 88
|
||||
fst.d $f30, $sp, 96
|
||||
fst.d $f31, $sp, 104
|
||||
ST ALPHA_R,$sp, 112
|
||||
ST ALPHA_I,$sp, 120
|
||||
|
||||
@@ -2300,15 +2300,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
LDARG $r25, $sp, 16
|
||||
LDARG $r26, $sp, 24
|
||||
LDARG $r27, $sp, 32
|
||||
LD $f23, $sp, 40
|
||||
LD $f24, $sp, 48
|
||||
LD $f25, $sp, 56
|
||||
LD $f26, $sp, 64
|
||||
LD $f27, $sp, 72
|
||||
LD $f28, $sp, 80
|
||||
LD $f29, $sp, 88
|
||||
LD $f30, $sp, 96
|
||||
LD $f31, $sp, 104
|
||||
fld.d $f23, $sp, 40
|
||||
fld.d $f24, $sp, 48
|
||||
fld.d $f25, $sp, 56
|
||||
fld.d $f26, $sp, 64
|
||||
fld.d $f27, $sp, 72
|
||||
fld.d $f28, $sp, 80
|
||||
fld.d $f29, $sp, 88
|
||||
fld.d $f30, $sp, 96
|
||||
fld.d $f31, $sp, 104
|
||||
|
||||
addi.d $sp, $sp, 128
|
||||
jirl $r0, $r1, 0x0
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user