Compare commits

...
Author SHA1 Message Date
Martin Kroeker e0166008be Update version to 0.3.34
arm64 graviton cirun / build (cmake, gfortran) (push) Canceled after 0s
arm64 graviton cirun / build (make, gfortran) (push) Canceled after 0s
Nightly-Homebrew-Build / build-OpenBLAS-with-Homebrew (push) Canceled after 0s
c910v qemu test / TEST (riscv64-linux-gnu, NO_SHARED=1 TARGET=C910V, C910V, riscv64-unknown-linux-gnu) (push) Canceled after 0s
c910v qemu test / TEST (riscv64-linux-gnu, NO_SHARED=1 TARGET=RISCV64_GENERIC, RISCV64_GENERIC, riscv64-linux-gnu) (push) Canceled after 0s
Run codspeed benchmarks / benchmarks (make, gfortran, ubuntu-22.04, 3.12) (push) Canceled after 0s
continuous build / build (cmake, clang, flang, ubuntu-latest) (push) Canceled after 0s
continuous build / build (cmake, clang, gfortran, macos-latest) (push) Canceled after 0s
continuous build / build (cmake, clang, gfortran, ubuntu-24.04-arm) (push) Canceled after 0s
continuous build / build (cmake, clang, gfortran, ubuntu-latest) (push) Canceled after 0s
continuous build / build (cmake, clang-21, flang, ubuntu-latest) (push) Canceled after 0s
continuous build / build (cmake, clang-21, gfortran, ubuntu-24.04-arm) (push) Canceled after 0s
continuous build / build (cmake, clang-21, gfortran, ubuntu-latest) (push) Canceled after 0s
continuous build / build (cmake, gcc, flang, ubuntu-latest) (push) Canceled after 0s
continuous build / build (cmake, gcc, gfortran, ubuntu-24.04-arm) (push) Canceled after 0s
continuous build / build (cmake, gcc, gfortran, ubuntu-latest) (push) Canceled after 0s
continuous build / build (make, clang, flang, ubuntu-latest) (push) Canceled after 0s
continuous build / build (make, clang, gfortran, macos-latest) (push) Canceled after 0s
continuous build / build (make, clang, gfortran, ubuntu-24.04-arm) (push) Canceled after 0s
continuous build / build (make, clang, gfortran, ubuntu-latest) (push) Canceled after 0s
continuous build / build (make, clang-21, flang, ubuntu-latest) (push) Canceled after 0s
continuous build / build (make, clang-21, gfortran, ubuntu-24.04-arm) (push) Canceled after 0s
continuous build / build (make, clang-21, gfortran, ubuntu-latest) (push) Canceled after 0s
continuous build / build (make, gcc, flang, ubuntu-latest) (push) Canceled after 0s
apple m / build-windows (cmake, gfortran, 0, 0) (push) Canceled after 0s
continuous build / build (make, gcc, gfortran, ubuntu-24.04-arm) (push) Canceled after 0s
apple m / build-windows (cmake, gfortran, 0, 1) (push) Canceled after 0s
continuous build / build (make, gcc, gfortran, ubuntu-latest) (push) Canceled after 0s
continuous build / msys2 (None, mingw-w64-ucrt-x86_64-fc, int32, UCRT64, mingw-w64-ucrt-x86_64) (push) Canceled after 0s
apple m / build-windows (cmake, gfortran, 1, 0) (push) Canceled after 0s
continuous build / msys2 (Release, <nil>, int32, MINGW32, mingw-w64-i686) (push) Canceled after 0s
apple m / build-windows (cmake, gfortran, 1, 1) (push) Canceled after 0s
continuous build / msys2 (Release, mingw-w64-clang-x86_64-fc, int32, CLANG64, mingw-w64-clang-x86_64) (push) Canceled after 0s
continuous build / msys2 (Release, mingw-w64-clang-x86_64-fc, int64, -DBINARY=64 -DINTERFACE64=1, CLANG64, mingw-w64-clang-x86_64) (push) Canceled after 0s
apple m / build-windows (make, gfortran, 0, 0) (push) Canceled after 0s
continuous build / msys2 (Release, mingw-w64-ucrt-x86_64-fc, int32, UCRT64, mingw-w64-ucrt-x86_64) (push) Canceled after 0s
continuous build / msys2 (Release, mingw-w64-ucrt-x86_64-fc, int64, -DBINARY=64 -DINTERFACE64=1, UCRT64, mingw-w64-ucrt-x86_64) (push) Canceled after 0s
apple m / build-windows (make, gfortran, 0, 1) (push) Canceled after 0s
continuous build / linux_thread_stress (openmp) (push) Canceled after 0s
apple m / build-windows (make, gfortran, 1, 0) (push) Canceled after 0s
continuous build / linux_thread_stress (pthread) (push) Canceled after 0s
continuous build / linux_thread_sanitizer (push) Canceled after 0s
apple m / build-windows (make, gfortran, 1, 1) (push) Canceled after 0s
continuous build / linux_thread_sanitizer_openmp (push) Canceled after 0s
apple m / xbuild-x86_64 (push) Canceled after 0s
continuous build / msys2_thread_stress (push) Canceled after 0s
apple m / xbuild-ios (push) Canceled after 0s
apple m / xbuild-ios32 (push) Canceled after 0s
continuous build / cross_build (DYNAMIC_ARCH=1 TARGET=GENERIC, mips64el, mips64el-linux-gnuabi64) (push) Canceled after 0s
continuous build / cross_build (TARGET=EV4, alpha, alpha-linux-gnu) (push) Canceled after 0s
continuous build / cross_build (TARGET=MIPS1004K, mipsel, mipsel-linux-gnu) (push) Canceled after 0s
continuous build / cross_build (TARGET=RISCV64_GENERIC, riscv64, riscv64-linux-gnu) (push) Canceled after 0s
continuous build / neoverse_build (push) Canceled after 0s
continuous build / neoverse_n1_build (push) Canceled after 0s
continuous build / neoverse_n1_omp_build (push) Canceled after 0s
continuous build / neoverse_n1_ilp64_build (push) Canceled after 0s
harmonyos / build (push) Canceled after 0s
loongarch64 qemu test / TEST (NO_SHARED=1 DYNAMIC_ARCH=1 TARGET=GENERIC, DYNAMIC_ARCH, loongarch64-linux-gnu) (push) Canceled after 0s
loongarch64 qemu test / TEST (NO_SHARED=1 DYNAMIC_ARCH=1 TARGET=LA264, LA264, loongarch64-linux-gnu) (push) Canceled after 0s
loongarch64 qemu test / TEST (NO_SHARED=1 DYNAMIC_ARCH=1 TARGET=LA464, LA464, loongarch64-linux-gnu) (push) Canceled after 0s
loongarch64 qemu test / TEST (NO_SHARED=1 DYNAMIC_ARCH=1 TARGET=LA64_GENERIC, LA64_GENERIC, loongarch64-linux-gnu) (push) Canceled after 0s
loongarch64 qemu test / TEST (NO_SHARED=1 DYNAMIC_ARCH=1 TARGET=LOONGSON2K1000, LOONGSON2K1000, loongarch64-linux-gnu) (push) Canceled after 0s
loongarch64 qemu test / TEST (NO_SHARED=1 DYNAMIC_ARCH=1 TARGET=LOONGSON3R5, LOONGSON3R5, loongarch64-linux-gnu) (push) Canceled after 0s
loongarch64 qemu test / TEST (NO_SHARED=1 DYNAMIC_ARCH=1 TARGET=LOONGSONGENERIC, LOONGSONGENERIC, loongarch64-linux-gnu) (push) Canceled after 0s
loongarch64 clang qemu test / TEST (NO_SHARED=1 DYNAMIC_ARCH=1 TARGET=GENERIC, DYNAMIC_ARCH) (push) Canceled after 0s
loongarch64 clang qemu test / TEST (NO_SHARED=1 DYNAMIC_ARCH=1 TARGET=LA264, LA264) (push) Canceled after 0s
loongarch64 clang qemu test / TEST (NO_SHARED=1 DYNAMIC_ARCH=1 TARGET=LA464, LA464) (push) Canceled after 0s
loongarch64 clang qemu test / TEST (NO_SHARED=1 DYNAMIC_ARCH=1 TARGET=LA64_GENERIC, LA64_GENERIC) (push) Canceled after 0s
loongarch64 clang qemu test / TEST (NO_SHARED=1 DYNAMIC_ARCH=1 TARGET=LOONGSON2K1000, LOONGSON2K1000) (push) Canceled after 0s
loongarch64 clang qemu test / TEST (NO_SHARED=1 DYNAMIC_ARCH=1 TARGET=LOONGSON3R5, LOONGSON3R5) (push) Canceled after 0s
loongarch64 clang qemu test / TEST (NO_SHARED=1 DYNAMIC_ARCH=1 TARGET=LOONGSONGENERIC, LOONGSONGENERIC) (push) Canceled after 0s
mips64 qemu test / TEST (NO_SHARED=1 TARGET=I6400, I6400, mipsisa64r6el-linux-gnuabi64) (push) Canceled after 0s
mips64 qemu test / TEST (NO_SHARED=1 TARGET=I6500, I6500, mipsisa64r6el-linux-gnuabi64) (push) Canceled after 0s
mips64 qemu test / TEST (NO_SHARED=1 TARGET=MIPS64_GENERIC, MIPS64_GENERIC, mips64el-linux-gnuabi64) (push) Canceled after 0s
mips64 qemu test / TEST (NO_SHARED=1 TARGET=P6600, P6600, mipsisa64r6el-linux-gnuabi64) (push) Canceled after 0s
mips64 qemu test / TEST (NO_SHARED=1 TARGET=SICORTEX, SICORTEX, mips64el-linux-gnuabi64) (push) Canceled after 0s
riscv64 zvl256b qemu test / TEST (TARGET=RISCV64_GENERIC BINARY=64 ARCH=riscv64 DYNAMIC_ARCH=1, rv64,g=true,c=true,v=true,vext_spec=v1.0,vlen=256,elen=64, DYNAMIC_ARCH=1) (push) Canceled after 0s
riscv64 zvl256b qemu test / TEST (TARGET=RISCV64_ZVL128B BINARY=64 ARCH=riscv64, rv64,g=true,c=true,v=true,vext_spec=v1.0,vlen=128,elen=64, RISCV64_ZVL128B) (push) Canceled after 0s
riscv64 zvl256b qemu test / TEST (TARGET=RISCV64_ZVL256B BINARY=64 ARCH=riscv64 BUILD_BFLOAT16=1 BUILD_HFLOAT16=1, rv64,g=true,c=true,v=true,vext_spec=v1.0,vlen=256,elen=64,zfh=true,zvfh=true,zvfbfwma=true, RISCV64_ZVL256B) (push) Canceled after 0s
2026-07-16 21:53:40 +02:00
Martin Kroeker 45e68d2240 Update version to 0.3.34 2026-07-16 21:52:30 +02:00
Martin Kroeker c13a003e40 Merge pull request #5922 from OpenMathLib/develop
Update from develop for 0.3.34 release
2026-07-16 21:51:15 +02:00
Martin Kroeker 07690084bf Update changelog for 0.3.34 (#5897)
* Update for 0.3.34
2026-07-16 21:48:07 +02:00
Martin Kroeker 55d6e6b98c Merge pull request #5921 from martin-frbg/issue5905
Mark temporaries as volatile to avoid SIGBUS in multithreaded builds with gcc15+ on 32bit FreeBSD/x86
2026-07-16 21:39:26 +02:00
Martin Kroeker bf7f06d9ac Mark temporaries as volatile to avoid SIGBUS in multithreading with gcc15+ on 32bit FreeBSD/x86 2026-07-16 18:42:23 +02:00
Martin Kroeker 739b2f084c Mark temporaries as volatile to avoid SIGBUS in multithreading with gcc15+ on 32bit FreeBSD/x86 2026-07-16 18:40:45 +02:00
Martin Kroeker 9ce1d6ff2a Mark temporaties as volatile to avoid SIGBUS in multithreading with gcc15+ on 32bit FreeBSD/x86 2026-07-16 18:39:06 +02:00
Martin Kroeker 15351019ea Mark subbuffer as volatile to fix SIGBUS in multithreading with gcc15+ on 32bit FreeBSD/x86 2026-07-16 18:35:14 +02:00
Martin Kroeker dd69b9d0ce Mark floats as volatile to fix SIGBUS in multithreading with gcc15+ on 32bit FreeBSD/x86 2026-07-16 18:33:19 +02:00
Martin Kroeker cefdaed87c translate BSD's i386 hostarch name and automatically set BINARY=32 for it 2026-07-16 18:30:17 +02:00
Martin Kroeker 43f9441317 Merge pull request #5920 from martin-frbg/lapack1245
Avoid large intermediates in (C/Z)LARTG (Reference-LAPACK PR 1245)
2026-07-16 01:12:38 +02:00
Martin Kroeker 53b14986de Avoid large intermediates in (C/Z)LARTG (Reference-LAPACK PR 1245) 2026-07-15 20:59:17 +02:00
Martin Kroeker 3e48730742 Add transpose support for C in GEADD (fixes #4646) (#5913)
* Add transpose support for C in GEADD (fixes #4646)

Extends GEADD to support independent transposition of both A and C,
matching the behavior of cuBLAS's geam and Apple's Accelerate geadd.
Previously only A could be transposed.

- Add transc parameter across cblas.h, common_interface.h,
  common_level3.h, common_param.h
- Add transc handling to interface/geadd.c and interface/zgeadd.c
- Extend kernel/generic/geadd.c and kernel/generic/zgeadd.c with
  stride logic for transposed C
- Add transpose test coverage (hand-verified 2x2 cases and randomized
  large-matrix tests) for sgeadd, dgeadd, cgeadd, zgeadd

* Add self to CONTRIBUTORS.md
2026-07-15 18:34:43 +02:00
Martin Kroeker dc3aa2cbd9 Fix non-SVE ARM64 potentially using non-zeroed register in SDOT/DDOT accumulation (#5918)
* Zero d0 register as it may not be identical with OUT, amend clobber list

* Add sdot/ddot reproducer from issue 5917 as ARM64-specific utest
2026-07-15 17:30:11 +02:00
aadityansha06 aade7ec2ff Add self to CONTRIBUTORS.md 2026-07-15 17:12:31 +05:30
aadityansha06 2c6bf39e4e Add transpose support for C in GEADD (fixes #4646)
Extends GEADD to support independent transposition of both A and C,
matching the behavior of cuBLAS's geam and Apple's Accelerate geadd.
Previously only A could be transposed.

- Add transc parameter across cblas.h, common_interface.h,
  common_level3.h, common_param.h
- Add transc handling to interface/geadd.c and interface/zgeadd.c
- Extend kernel/generic/geadd.c and kernel/generic/zgeadd.c with
  stride logic for transposed C
- Add transpose test coverage (hand-verified 2x2 cases and randomized
  large-matrix tests) for sgeadd, dgeadd, cgeadd, zgeadd
2026-07-15 17:12:31 +05:30
Martin Kroeker b338322e9a Merge pull request #5900 from mpwaser/fix/c910v-qemu-utest-timeout
Relax C910V qemu utest timeout
2026-07-15 11:27:06 +02:00
Martin Kroeker 6604a7277c Merge pull request #5916 from martin-frbg/lapack1289
Fix workspace queries for TZRZF/UNMRZ in ?GELSY (Reference-LAPACK PR1289/1325)
2026-07-15 07:56:46 +02:00
Martin Kroeker 75b8a2ce93 Fix parameter queries for TZRZF/UNMRZ in ?GELSY (Reference-LAPACK PR 1289&1325) 2026-07-14 22:14:02 +02:00
Martin Kroeker b28cdccd2d Merge pull request #5915 from martin-frbg/fixup5802
Rework the -mpwr10 option to be only applied to POWER9/10 on FreeBSD
2026-07-14 22:05:19 +02:00
Martin Kroeker 036e835019 Merge pull request #5912 from martin-frbg/lapack1288
Fix seed advancement in SLARUV/DLARUV (Reference-LAPACK PR 1288)
2026-07-14 20:30:43 +02:00
Martin Kroeker fd88cac200 Merge pull request #5911 from martin-frbg/lapack1305
Replace HUGE intrinsic in ?TGSJA for consistency (Reference-LAPACK PR 1305)
2026-07-14 17:58:23 +02:00
Martin Kroeker 87aac59e87 Rework the -mpwr10 option to be only applied to POWER9/10 on FreeBSD 2026-07-14 16:27:16 +02:00
Martin Kroeker 1e14cc90f8 Merge pull request #5910 from martin-frbg/lapack1298
Fix test failures in ?CHKLQ when NB=1 with M=N (Reference-LAPACK PR 1298)
2026-07-14 15:44:45 +02:00
Martin Kroeker 136a714687 Merge pull request #5914 from martin-frbg/u74detect
Add cpu detection for Sifive U74
2026-07-14 15:20:31 +02:00
Martin Kroeker a5dcb2a8a8 Merge pull request #5909 from hmeiland/riscv64-blas-set-parameter
RISC-V: cache-aware GEMM blocking (get_L2_size + blas_set_parameter)
2026-07-14 12:27:10 +02:00
Martin Kroeker 41aad1107a Add Sifive U74 2026-07-14 07:30:47 +02:00
Martin Kroeker 873f005957 Merge pull request #5903 from hmeiland/u74-gemm-4x4-kernel
Add SiFive U74 target with a scalar 4×4 register-tiled GEMM kernel
2026-07-14 07:27:12 +02:00
Martin Kroeker 6b1d101317 Fix seed advancement on rejected uniform deviate (Reference-LAPACK PR 1288) 2026-07-13 19:56:29 +02:00
Martin Kroeker cdde6e8c4d Replace HUGE intrinsic (Reference-LAPACK PR 1305) 2026-07-13 19:50:05 +02:00
Martin Kroeker 5e517085c5 Fix test failures when NB=1 with M=N (Reference-LAPACK PR 1298) 2026-07-13 19:40:43 +02:00
Martin Kroeker 65382d22d4 Merge pull request #5583 from vtjnash/fix-libnamesuffix-handling
build: Fix LIBNAMESUFFIX handling in CMake documentation
2026-07-13 16:59:12 +02:00
Hugo Meiland 5d7868f487 U74 target: move the U74-specific gemm kernel to kernel/riscv64
Per review, the U74-specific DGEMM micro-kernel does not belong under
kernel/generic (reserved for portable, architecture-neutral C kernels).
Move both the hybrid dispatcher and its readable assembly source into
kernel/riscv64, next to KERNEL.U74:

- git mv kernel/generic/gemmkernel_4x4_u74.c -> kernel/riscv64/
- git mv kernel/generic/kern_u74.S          -> kernel/riscv64/
- KERNEL.U74: DGEMMKERNEL ../generic/gemmkernel_4x4_u74.c
                       -> ../riscv64/gemmkernel_4x4_u74.c
- gemmkernel_4x4_u74.c: #include "conversion_macros.h"
                     -> #include "../generic/conversion_macros.h"
  (that header stays under kernel/generic; same form kernel/wasm
   already uses for it)

No functional change. The portable gemmkernel_4x4.c (SGEMMKERNEL) is
untouched and stays in kernel/generic. DGEMMKERNEL still resolves through
$(KERNELDIR), so both the Makefile ($(KERNELDIR)/$(DGEMMKERNEL)) and CMake
(GenerateNamedObjects "${KERNELDIR}/${DGEMMKERNEL}") builds pick the kernel
up from its new location.
2026-07-13 16:37:03 +02:00
Martin Kroeker 113410db3e Merge pull request #5904 from moluopro/fix/xerbla-handler
Add a portable XERBLA handler API
2026-07-13 15:15:03 +02:00
Martin Kroeker b668c9a376 Merge pull request #5808 from nh2/issue-5806-openblas_set_num_threads-openmp
Make OpenBLAS's usage of OpenMP respect `openblas_set_num_threads()`
2026-07-13 14:38:03 +02:00
Martin Kroeker 65b51b0c12 Merge pull request #5908 from moluopro/cleanup/remove-misplaced-lapacke-wrappers
Remove misplaced LAPACKE `?gesvdq_work` source files
2026-07-13 13:32:18 +02:00
Hugo Meiland 269e1cd505 RISC-V: add get_L2_size() and blas_set_parameter() for cache-aware GEMM blocking
RISC-V was the only major architecture without a get_L2_size() /
blas_set_parameter() implementation, so the GEMM cache-blocking parameters
(P/Q/R) were fixed at compile time regardless of the actual L2 cache size.

Because the blocking is now derived from the L2 cache detected at runtime
rather than a fixed compile-time constant, future RISC-V cores - which are
arriving with progressively larger and more varied L2 caches - get more
optimal blocking automatically, and the port gains the same runtime-tuning
hook x86 and LoongArch already use.

This adds, under ARCH_RISCV64:

- get_L2_size(): reads the level-2 (unified) cache size from Linux sysfs
  (/sys/devices/system/cpu/cpu0/cache/index*/{level,size}); RISC-V has no
  architectural cache-size query like x86 CPUID or LoongArch CPUCFG. Falls
  back to 512 KB when sysfs is unavailable.

- blas_set_parameter(): scales each precision's packed-A dimension P from the
  detected L2. The base blocking and the reference cache size come from the
  active core's own param.h block (*_DEFAULT_P_BASE, RISCV_L2_REFERENCE_KB),
  so the function carries no core-specific constants and is a no-op for cores
  that do not opt in. Q and R keep their param.h defaults.

- driver/others/memory.c and common_macro.h: add ARCH_RISCV64 to the existing
  architecture lists that call blas_set_parameter() and declare the runtime
  parameter variables (sgemm_p, dgemm_p, ...).

- param.h RISCV64_ZVL256B: declares the per-core base blocking + reference and
  maps SGEMM/DGEMM/CGEMM/ZGEMM DEFAULT_P to the runtime variables for static
  builds; DYNAMIC_ARCH keeps the literals, since kernel/setparam-ref.c
  init_parameter() initialises the gotoblas table from these macros and
  blas_set_parameter() is not called on the dynamic path.

Only RISCV64_ZVL256B opts in so far; its base + reference are tuned on the
SpaceMiT X60, where a 512 KB L2 reproduces the stock blocking, so this is
performance-neutral on current hardware. Verified: a static RISCV64_ZVL256B
build reproduces the stock 128/128/16384 (SGEMM) and 64/128/8192 (DGEMM)
blocking; a DYNAMIC_ARCH build compiles cleanly (per-core setparam-ref objects
build without error); and get_L2_size() reads the correct size on both a
SpaceMiT X60 (512 KB L2) and a SiFive U74 / VisionFive 2 (2 MB L2).
2026-07-13 11:00:15 +02:00
moluopro 0f68da835c Remove misplaced LAPACKE GESVDQ wrapper sources
These stale duplicate sources are not referenced by the build. The canonical implementations remain under lapack-netlib/LAPACKE/src.

Signed-off-by: moluopro <moluopro@qq.com>
2026-07-13 12:40:03 +08:00
Niklas Hambüchen f8674a7be8 Make OpenBLAS's usage of OpenMP respect openblas_set_num_threads(). Fixes #5806.
Until now, the code in `num_cpu_avail()`,

    if (blas_cpu_number != openmp_nthreads) {
      goto_set_num_threads(openmp_nthreads);
    }

would just always set the threads back to OpenMP's thread count.
2026-07-12 06:11:17 +02:00
moluopro 6720959694 docs: summarize XERBLA handler semantics 2026-07-11 20:02:43 +08:00
moluopro 477131d547 cblas: clarify XERBLA handler lifetime 2026-07-11 20:02:13 +08:00
moluopro 03cfefcdcb cmake: propagate CBLAS test failures on Windows 2026-07-11 19:53:42 +08:00
moluopro 8ac41809cf test: register XERBLA for level 3 BLAS 2026-07-11 19:52:20 +08:00
moluopro e4891bc055 test: register XERBLA for level 2 BLAS 2026-07-11 19:50:56 +08:00
moluopro 7a24cf7a6a test: harden Makefile result handling 2026-07-11 19:49:33 +08:00
moluopro b5fa89f351 cmake: harden regular BLAS error tests 2026-07-11 19:48:33 +08:00
moluopro 066e9076c3 test: add a regular BLAS XERBLA bridge 2026-07-11 19:47:54 +08:00
moluopro 97abc61bfc docs: clarify XERBLA handler behavior on ELF 2026-07-10 20:40:50 +08:00
moluopro d093ab90e9 docs: clarify XERBLA handler concurrency 2026-07-10 15:54:19 +08:00
moluopro ed8f1198b2 utest: bound XERBLA routine name diagnostics 2026-07-10 15:40:02 +08:00
moluopro f07e6a3d0d exports: preserve Windows ordinals in Perl generator 2026-07-10 15:39:22 +08:00
moluopro 490721cbd9 exports: preserve Windows ordinals for new symbols 2026-07-10 15:38:26 +08:00
moluopro 5daa61827a ctest: fail level-3 error-exit mismatches 2026-07-10 15:04:13 +08:00
moluopro cd4786dd78 ctest: fail level-2 error-exit mismatches 2026-07-10 15:03:18 +08:00
moluopro 39526d88c9 ctest: add a fatal test failure helper 2026-07-10 15:02:17 +08:00
moluopro 99bb32ae59 ctest: use explicit XERBLA handlers in error tests 2026-07-10 15:00:36 +08:00
moluopro 29703e52ad utest: cover explicit XERBLA handler registration 2026-07-10 14:59:30 +08:00
moluopro d7e007e0fb docs: document XERBLA handler semantics 2026-07-10 14:58:35 +08:00
moluopro 8da645954b exports: expose the XERBLA handler setter 2026-07-10 14:56:48 +08:00
moluopro 6a04925804 xerbla: add a portable handler API 2026-07-10 14:55:52 +08:00
moluopro b2ba228de5 install: preserve callback typedefs in generated CBLAS headers 2026-07-10 14:54:02 +08:00
moluopro 992ea2dab5 cmake: preserve callback typedefs in generated CBLAS headers 2026-07-10 14:53:18 +08:00
hmeiland d6e64e8032 U74 target: add CMake build support
Mirror the RISCV64_GENERIC target blocks for U74 in cmake/prebuild.cmake
(cache defines: 32 KiB L1D / 2 MiB L2, 64 B lines, matching getarch),
cmake/system.cmake and cmake/cc.cmake
(-march=rv64imafdc_zba_zbb -mabi=lp64d -mtune=sifive-u74), so
'cmake -DTARGET=U74' builds alongside the Makefile path.

Verified on a VisionFive 2: configure recognizes the target and a full
'cmake --build' produces libopenblas.a with the U74 march/mtune flags
applied to the kernel objects (0 errors).
2026-07-10 06:36:10 +02:00
hmeiland cfdaa69b9f U74 asm kernel: note full-memory HPL result in header
Full-memory HPL N=27456 (asm hybrid + Q=256) measured at 5.99 GFLOPS
(residual PASSED, ~50% of the 12 GF peak, +10.7% over the tuned C kernel,
1.81x the stock 2x2) - the best clean figure. Doc-only header update.
2026-07-10 05:44:15 +02:00
hmeiland 4999e881a5 U74 target: hand-scheduled scalar asm DGEMM micro-kernel
Adds a hand-written RV64GC scalar 4x4 DGEMM micro-kernel (kern_u74.S) and
wires it as the U74 DGEMMKERNEL via a hybrid dispatcher
(gemmkernel_4x4_u74.c): the fast path (bm,bn multiples of 4, even bk,
non-TRMM) runs the asm; all other shapes, odd bk, and the TRMM builds fall
back to the portable C 4x4 kernel.

The asm uses a 4x4 register tile (16 accumulators), full operand double-
buffering (P/Q ping-pong) with one-iteration lookahead, and load-before-FMA
issue ordering matched to the U74's dual-issue in-order front end.  Probes
show this reaches the FP-pipe peak (~16.5 cycles / 16 fmadd.d = 2.9 GF on
L1-resident data); the streaming plateau is memory-latency-bound, not the
schedule.

Measured on a VisionFive 2 (single-core, KC=256): micro-kernel 1.88 vs 1.54
GF (+22%), full blocked DGEMM 1.77 vs 1.48 GF (+20%); the advantage holds
under 4-core contention (+17%).  End-to-end HPL N=10000 (4 cores, Q=256):
5.17 vs 4.97 GF (+4.0%), residual PASSED.  Correctness validated against the
full BLAS Level-3 test suite (DGEMM 17,496 computational calls, 0 failures).
kern_u74.S is the readable source; the .c embeds it via top-level __asm__ so
it builds as a single OpenBLAS kernel object with no build-system changes.
2026-07-10 03:31:45 +02:00
hmeiland e4228c3255 U74 target: raise DGEMM_DEFAULT_Q to 256
A same-board controlled HPL A/B (VisionFive 2, TARGET=U74, N=10000,
NB=192, 2x2 grid, both libraries clean-built, residual PASSED) measures
4.97 vs 4.86 GFLOPS (+2.25%) for DGEMM_Q=256 over the inherited 128; at
a memory-filling N=27456 the tuned build sustains 5.41 vs 5.24 GFLOPS
(+3.24%). With HPL's NB=192, KC=256>=192 lets each trailing-update K
panel run in a single KC block, halving the C read-modify-write traffic
versus KC=128 (which splits K=192 into 128+64). A single-core P/Q sweep
over the real packing + micro-kernel objects confirms the GEMM is
compute-bound (whole grid within 3%), so P and R are left unchanged;
SGEMM_Q was already 240.
2026-07-10 01:26:18 +02:00
hmeiland b8949d1663 U74 target: build for the full JH7110 ISA (add Zba/Zbb)
The StarFive JH7110's U74 cores implement rv64imafdc_..._zba_zbb, so the U74
target now compiles with -march=rv64imafdc_zba_zbb. The generic RISCV64_GENERIC
target stays at bare rv64imafdc for portability across unknown RV64GC cores.

Measured on the VisionFive 2 (GCC 13.3, -mtune=sifive-u74 held constant): GCC
emits Zba shift-add instructions in the packing routines, but DGEMM is unchanged
-- the 4x4 kernel holds 1.533 GF either way and packing 1.74 vs 1.75 GB/s. The
4x4 micro-kernel is FMA-bound (fused fmadd.d with immediate-offset loads) and
packing is LPDDR4-bandwidth-bound, so integer address generation is not on the
critical path. The flag is nonetheless the correct -march for the silicon, is
free, and can only help address-gen-bound code elsewhere in the library. The
remaining GEMM headroom on the U74 is microarchitectural scheduling (a
hand-written assembly micro-kernel), not the ISA.
2026-07-09 20:21:40 +02:00
mpwaser e127edeb5e Relax C910V qemu utest timeout 2026-07-09 14:10:00 +02:00
hmeiland a3620c264a Add U74 target with a 4x4 register-tiled GEMM kernel
The SiFive U74 (RV64GC; e.g. StarFive JH7110 / VisionFive 2) is a scalar,
in-order core with no RVV, so today it falls back to RISCV64_GENERIC whose
S/D GEMM uses the generic 2x2 C micro-kernel.

Per the U74 Core Complex Manual (Table 169) fmadd.d has a 7-cycle latency
at repeat rate 1 (fully pipelined). A 2x2 tile exposes only 4 independent
accumulator chains -- fewer than the FMA latency -- so the FP pipe stalls
on the accumulator dependency, and the 1:1 load:FMA ratio saturates the
single load/store pipe ("only one outstanding line fill", manual 8.2).

This adds a portable 4x4 GEMM micro-kernel and a dedicated U74 target:

- kernel/generic/gemmkernel_4x4.c: 16-accumulator 4x4 register tile. 16
  independent chains exceed the 7-cycle latency, and the load:FMA ratio
  drops to 1:2. 16 acc + 4 A + 4 B fit RV64G's 32 FP registers without
  spilling. Full 4/2/1 edge handling in both M and N.

- U74 target wiring: getarch.c (FORCE_U74, 32 KiB/64 B L1D, 2 MiB L2),
  param.h (S/D UNROLL 4/4; complex stays 2/2), kernel/riscv64/KERNEL.U74
  (S/D GEMM -> gemmkernel_4x4 + gemm_[nt]copy_4; S/D TRMM -> existing
  trmmkernel_4x4), Makefile.prebuild + Makefile.riscv64 (-mtune=sifive-u74),
  TargetList.txt, cpuid_riscv64.c.

The 4x4 kernel was verified numerically against a naive reference GEMM,
driven through the real gemm_tcopy_4 / gemm_ncopy_4 packing routines,
across 27,436 M/N/K x alpha combinations covering every 4/2/1 tail case:
worst absolute error 0.

Build with: make TARGET=U74
2026-07-09 14:00:16 +02:00
Jameson NashandClaude Opus 4.5 4026d7ba7c Fix LIBNAMESUFFIX handling in CMake and update documentation
- Fix cmake/system.cmake: LIBPREFIX was incorrectly overwritten when
  LIBNAMESUFFIX was defined, losing both "lib" prefix and "openblas"
- Fix Makefile.rule docs: typo used LIBNAMESUFFIX instead of LIBNAMEPREFIX
- Fix Makefile.rule docs: removed misleading underscores from examples
- Fix docs/build_system.md: removed incorrect claim about automatic
  underscore separator

The implementation does not add an underscore before the suffix - users
who want a separator should include it in their LIBNAMESUFFIX value
(e.g., LIBNAMESUFFIX=_omp).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 13:33:59 -05:00
104 changed files with 3712 additions and 2117 deletions
+5 -4
View File
@@ -93,8 +93,9 @@ jobs:
run: |
run_with_retry() {
local cmd="$1"
local time_out=10
local retries=10
local time_out="${2:-10}"
local retries="${3:-10}"
local timeout_step="${4:-5}"
local attempt=0
for ((i=1; i<=retries; i++)); do
@@ -106,7 +107,7 @@ jobs:
local exit_code=$?
if [ $exit_code -eq 140 ]; then
echo "Attempt $i timed out (retrying...)"
time_out=$((time_out + 5))
time_out=$((time_out + timeout_step))
else
echo "Attempt $i failed with exit code $exit_code. Aborting workflow."
exit $exit_code
@@ -121,7 +122,7 @@ jobs:
export PATH=$GITHUB_WORKSPACE/qemu-install/bin:$PATH
which qemu-riscv64
export QEMU_BIN=$(which qemu-riscv64)
run_with_retry "$QEMU_BIN ./utest/openblas_utest"
run_with_retry "$QEMU_BIN ./utest/openblas_utest" 120 2 30
run_with_retry "$QEMU_BIN ./utest/openblas_utest_ext"
OPENBLAS_NUM_THREADS=2 qemu-riscv64 ./ctest/xscblat1
+37 -9
View File
@@ -9,7 +9,7 @@ project(OpenBLAS C ASM)
set(OpenBLAS_MAJOR_VERSION 0)
set(OpenBLAS_MINOR_VERSION 3)
set(OpenBLAS_PATCH_VERSION 33.dev)
set(OpenBLAS_PATCH_VERSION 34)
set(OpenBLAS_VERSION "${OpenBLAS_MAJOR_VERSION}.${OpenBLAS_MINOR_VERSION}.${OpenBLAS_PATCH_VERSION}")
@@ -734,18 +734,46 @@ if(NOT NO_CBLAS)
set(CBLAS_H ${CMAKE_BINARY_DIR}/generated/cblas.h)
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/cblas.h CBLAS_H_CONTENTS)
string(REPLACE "common" "openblas_config" CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS}")
# Symbol prefix/suffix settings rename exported functions, not C typedefs.
# Protect callback type names from the textual function-name rewriting below.
string(REPLACE "openblas_dojob_callback" "OPENBLAS_DOJOB_CALLBACK_TYPE"
CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS_NEW}")
string(REPLACE "openblas_threads_callback" "OPENBLAS_THREADS_CALLBACK_TYPE"
CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS_NEW}")
string(REPLACE "openblas_xerbla_handler" "OPENBLAS_XERBLA_HANDLER_TYPE"
CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS_NEW}")
if (NOT ${SYMBOLPREFIX} STREQUAL "")
string(REPLACE " cblas" " ${SYMBOLPREFIX}cblas" CBLAS_H_CONTENTS "${CBLAS_H_CONTENTS_NEW}")
string(REPLACE " openblas" " ${SYMBOLPREFIX}openblas" CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS}")
string (REPLACE " ${SYMBOLPREFIX}openblas_complex" " openblas_complex" CBLAS_H_CONTENTS "${CBLAS_H_CONTENTS_NEW}")
string(REPLACE " goto" " ${SYMBOLPREFIX}goto" CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS}")
string(REPLACE " cblas" " ${SYMBOLPREFIX}cblas"
CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS_NEW}")
string(REPLACE " openblas" " ${SYMBOLPREFIX}openblas"
CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS_NEW}")
string(REPLACE " ${SYMBOLPREFIX}openblas_complex" " openblas_complex"
CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS_NEW}")
string(REPLACE " goto" " ${SYMBOLPREFIX}goto"
CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS_NEW}")
endif()
if (NOT ${SYMBOLSUFFIX} STREQUAL "")
string(REGEX REPLACE "(cblas[^ (]*)" "\\1${SYMBOLSUFFIX}" CBLAS_H_CONTENTS "${CBLAS_H_CONTENTS_NEW}")
string(REGEX REPLACE "(openblas[^ (]*)" "\\1${SYMBOLSUFFIX}" CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS}")
string(REGEX REPLACE "(openblas_complex[^ ]*)${SYMBOLSUFFIX}" "\\1" CBLAS_H_CONTENTS "${CBLAS_H_CONTENTS_NEW}")
string(REGEX REPLACE "(goto[^ (]*)" "\\1${SYMBOLSUFFIX}" CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS}")
string(REGEX REPLACE "(cblas[A-Za-z0-9_]*)" "\\1${SYMBOLSUFFIX}"
CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS_NEW}")
string(REGEX REPLACE "(openblas[A-Za-z0-9_]*)" "\\1${SYMBOLSUFFIX}"
CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS_NEW}")
string(REPLACE "openblas_config${SYMBOLSUFFIX}" "openblas_config"
CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS_NEW}")
string(REGEX REPLACE "(openblas_complex[A-Za-z0-9_]*)${SYMBOLSUFFIX}" "\\1"
CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS_NEW}")
string(REGEX REPLACE "(goto[A-Za-z0-9_]*)" "\\1${SYMBOLSUFFIX}"
CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS_NEW}")
endif()
string(REPLACE "OPENBLAS_DOJOB_CALLBACK_TYPE" "openblas_dojob_callback"
CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS_NEW}")
string(REPLACE "OPENBLAS_THREADS_CALLBACK_TYPE" "openblas_threads_callback"
CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS_NEW}")
string(REPLACE "OPENBLAS_XERBLA_HANDLER_TYPE" "openblas_xerbla_handler"
CBLAS_H_CONTENTS_NEW "${CBLAS_H_CONTENTS_NEW}")
file(WRITE ${CBLAS_H} "${CBLAS_H_CONTENTS_NEW}")
install (FILES ${CBLAS_H} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
endif()
+5
View File
@@ -279,3 +279,8 @@ In chronological order:
* Nathan Sircombe <nathan.sircombe@arm.com>
* [2026-04-16] Add CPU ID for Neoverse V3
hheei <hheei@users.noreply.github.com>
* Aadityansha Verma <https://github.com/aadityansha06>
* [2026-07-14] Add independent transpose support for C in GEADD (sgeadd/dgeadd/cgeadd/zgeadd).
+110
View File
@@ -1,4 +1,114 @@
OpenBLAS ChangeLog
====================================================================
Version 0.3.34
16-Jul-2026
general:
- Fixed potential race conditions between concurrent calls to level3 BLAS
functions (inadvertent use of non-unified locks)
- Fixed potential race condition in GETRF
- Added or improved multithreading thresholds in SPR,SPR2,SYR,SYR2,TBMV,TPMV
- Added multithreading thresholds to GETRS, LAED3, LASWP, LAUUM, TRTRS, ZTRTRI
- Added a BLAS extension for overriding the default error handler (XERBLA) function
- Reimplemented the BLAS extension GEADD to support independent transposition of
both matrices (unlike the previous, ATLAS-like implementation)
- Guarded against spurious NaN values in the reimplemented ?LAED3
- Fixed compilation of the BLAS extension tests with CMake
- Fixed spurious and conflicting setting of job numbers in gmake builds
- Fixed a potential linking issue with the fortran runtime in the BLAS tests
- Fixed potential access to unrelated memory in the C fallback versions of LAPACK
functions ILAENV and IPARMQ
- Fixed the generated pkgfile to support spaces in path names
- Added support for compilation with the experimental, LLVM-based memory-safe C toolchain
known as Fil-C
- Imported recent updates from Reference-LAPACK to realign with its upcoming 3.13.0 release:
- Added non-trivial terminating case to ?LARFT calculation (Reference-LAPACK PR 1163)
- Fixed workspace calculation for CUNMLQ with K=0 (Reference-LAPACK PR 1225)
- Rearranged computations in C/ZLARTG to avoid large intermediates (PR 1245)
- Fixed wrong Y increment used in ?ORDB3/?UNBDB3 (Reference-LAPACK PR 1265)
- Fixed wrong name reported in XERBLA call of ZLA_SYRFSX_EXTENDED (PR 1268)
- Fixed wrong JOBA type in SGESVJ call of SGEJSV (Reference-LAPACK PR 1269)
- Fixed wrong workspace in DGEJSV corrupting memory in DGESVJ (PR 1270)
- Fixed wrong or missing EXTERNAL declarations (Reference-LAPACK PR 1271)
- Fixed wrong operand number in errors of GGSVD3,UN/ORBDB4,UN/ORCSD (PR 1272)
- Fixed sign of error flag in LWORK check of LAQZ0 (Reference-LAPACK PR 1273)
- Fixed too small workspace query result from SGGEV3 (Reference-LAPACK PR 1274)
- Fixed DLASWLQ not rejecting NB=0 (Reference-LAPACK PR 1275)
- Avoid immediate overflows in GEJSV,GESVJ,GESVDX,GEDMD (Reference-LAPACK PR 1283)
- Ignore LDU value when U unused in LAPACKE_?GESVD_WORK (Reference-LAPACK PR 1284)
- Fixed premature return before fallback code in BDSQR (Reference-LAPACK PR 1285)
- Increased tolerance in LASD2 to improve BDSDC stability (Reference-LAPACK PR 1286)
- Fixed row-major A dimension for SIDE=R in LAPACKE_?TPRFB_WORK (PR 1287)
- Fixed seed advancement in SLARUV/DLARUV (Reference-LAPACK PR 1288)
- Fixed workspace queries for TZRZF/UNMRZ in GELSY (Reference-LAPACK PRs 1289/1325)
- Avoid immediate overflows in ?LARFGP (Reference-LAPACK PR 1290)
- Added handling of degenerate cases in OR/UNCSD2BY1 (Reference-LAPACK PR 1291)
- Fixed workspace for tiny inputs in ORM/UNM-L/R-Q and -Q-L/R (PR 1292)
- Scaled convergence thresholds in ?BBCSD to improve accuracy (PR 1293)
- Fixed integer overflow in the LAPACKE nancheck helpers (Reference-LAPACK PR 1294)
- Relaxed eigenvalue consistency checks in testsuite (Reference-LAPACK PR 1297)
- Fixed test failures in ?CHKLQ with NB=1 and M=N (Reference-LAPACK PR 1298)
- Switched to QR algorithm in ?BDSDC for bidiagonal SVD with vectors (PR 1300)
- Replaced HUGE intrinsic in ?TGSJA with parameter for consistency (PR 1305)
- Corrected description of QMAX parameter in ?LASQ3 (Reference-LAPACK PR 1307)
- Fixed bad scaling in ?LARFF that slowed down DSYEVR/ZHEEVR (PR 1309)
- Fixed handling of negative increments in ?LARF/?LARF1F/?LARF1L (PR 1315)
- Increased tolerances in ?LAED to match changes in ?LASD (PR 1317)
- Fixed LAPACKE_?lacpy_work destroying data in row-major mode (PR 1318)
arm:
- Added a significantly faster SGEMM kernel
arm64:
- Added optimized kernels for OMATCOPY_CT and OMATCOPY_RT on all targets
- Fixed SDOT/DDOT on non-SVE-capable cpus not initializing the result correctly
- Fixed miscompilation of CGETF2/ZGETF2 by LLVM on Apple M
- Fixed SSYRK miscalculation on Apple M systems bigger than the Mac mini
- Fixed remaining cases of CMake build failure due to long argument lists on OSX
- On OSX, reduced the list of DYNAMIC_ARCH targets to those relevant for this os
- Fixed platform detection and cross-builds to iOS on OSX with AppleClang
- Fixed gmake builds for SME targets on OSX with AppleClang
- Improved the compiler test for SME compatibility in the CMake build files
- Fixed runtime detection of SME in DYNAMIC_ARCH builds made with CMake
- Restored a fix for building DYNAMIC_ARCH under Windows on Arm that was inadvertently
dropped in 0.3.33)
- Corrected the selection criteria for the SME-based SGEMM kernel on Apple M
- Fixed DYNAMIC_ARCH builds on hosts without SVE capability
- Fixed building a shared library with NAG Fortran on OSX
- Fixed misdetection of C11 capability (and resulting race conditions during concurrent
calls) in Clang builds under OSX
- Fixed miscalculation of Apple M cpu time leading to benchmarks 40 times too slow
loongarch64:
- Corrected generation of the LSX/LASX status flags in the configuration files
- Fixed potential reads of memory beyond the array bounds in the LA464 SGEMM kernel
- Added optimized SDOT, ICAMIN/IZAMIN and ZGEMM kernels for 2K3000
power:
- Fixed an incompatibility in the assembly kernels for SCAL on FreeBSD
- Fixed a potentially spurious check for gfortran in gmake builds with LLVM
that could make POWER9/10 builds fall back to POWER8 kernels
- Improved build flags and cpu register constraints for POWER10
- Fixed linking issues on BSD
riscv64:
- Fixed compilation for DYNAMIC_ARCH with BUILD_BFLOAT16 defined
- Fixed SGEMM and DGEMM errors on ZVL256 introduced in 0.3.33
- Sped up GEMV on C910V and ZVL256B targets
- Improved the x280 S/DROTM kernel and enabled it on ZVL128B/ZVL256B
- Added optimized STRSM kernels for ZVL128B/ZVL256B
- Added optimized D/C/ZTRSM kernels (RN and RT cases) for ZVL128B/ZVL256B
- Added a dedicated target for the SiFive U74 with optimized SGEMM and DGEMM kernels
- Made L2 cache size available at runtime for scaling GEMM block sizes
x86_64:
- Fixed remaining cases of CMake build failure due to long argument lists on OSX
- Improved cpu capability check for recent Zhaoxin cpus
- Fixed wrong TRSM results on AMD Barcelona (and Ryzen systems in 32bit builds)
- Added autodetection support for the fake Opteron-like CPUID used by QEMU on AMD hardware
- Fixed automatic setting of the BINARY=32 option when building with 32bit toolchains
- Fixed miscompilation of GEMM,SYR2K and TPMV kernels with gcc15/gcc16 on 32bit FreeBSD
====================================================================
Version 0.3.33
23-Apr-2026
+9 -2
View File
@@ -73,7 +73,10 @@ install : lib.grd
ifneq ($(NO_CBLAS),1)
@echo Generating cblas.h in $(DESTDIR)$(OPENBLAS_INCLUDE_DIR)
@cp cblas.h cblas.tmp
@sed -e 's/openblas_dojob_callback/OPENBLAS_DOJOB_CALLBACK_TYPE/g' \
-e 's/openblas_threads_callback/OPENBLAS_THREADS_CALLBACK_TYPE/g' \
-e 's/openblas_xerbla_handler/OPENBLAS_XERBLA_HANDLER_TYPE/g' \
cblas.h > cblas.tmp
ifdef SYMBOLPREFIX
@sed 's/cblas[^() ]*/$(SYMBOLPREFIX)&/g' cblas.tmp > cblas.tmp2
@sed 's/openblas[^() ]*/$(SYMBOLPREFIX)&/g' cblas.tmp2 > cblas.tmp
@@ -88,7 +91,11 @@ ifdef SYMBOLSUFFIX
@sed 's/\(openblas_complex_\)\([^ ]*\)$(SYMBOLSUFFIX)/\1\2 /g' cblas.tmp > cblas.tmp2
@sed 's/goto[^() ]*/&$(SYMBOLSUFFIX)/g' cblas.tmp2 > cblas.tmp
endif
@sed 's/common/openblas_config/g' cblas.tmp > "$(DESTDIR)$(OPENBLAS_INCLUDE_DIR)/cblas.h"
@sed -e 's/OPENBLAS_DOJOB_CALLBACK_TYPE/openblas_dojob_callback/g' \
-e 's/OPENBLAS_THREADS_CALLBACK_TYPE/openblas_threads_callback/g' \
-e 's/OPENBLAS_XERBLA_HANDLER_TYPE/openblas_xerbla_handler/g' \
-e 's/common/openblas_config/g' \
cblas.tmp > "$(DESTDIR)$(OPENBLAS_INCLUDE_DIR)/cblas.h"
endif
ifneq ($(OSNAME), AIX)
+6 -1
View File
@@ -111,7 +111,12 @@ endif
endif
ifeq ($(C_COMPILER), CLANG)
CCOMMON_OPT += -fno-integrated-as -Wa,-mpwr10
CCOMMON_OPT += -fno-integrated-as
ifeq ($(OSNAME), FreeBSD)
ifeq ($(CORE), $(filter $(CORE),POWER9 POWER10))
CCOMMON_OPT += -Wa,-mpwr10
endif
endif
endif
# workaround for C->FORTRAN ABI violation in LAPACKE
ifeq ($(F_COMPILER), GFORTRAN)
+4
View File
@@ -75,6 +75,10 @@ ifeq ($(TARGET), RISCV64_GENERIC)
TARGET_FLAGS = -march=rv64imafdc -mabi=lp64d
endif
ifeq ($(TARGET), U74)
TARGET_FLAGS = -march=rv64imafdc_zba_zbb -mabi=lp64d
endif
all: getarch_2nd
./getarch_2nd 0 >> $(TARGET_MAKE)
./getarch_2nd 1 >> $(TARGET_CONF)
+4
View File
@@ -25,3 +25,7 @@ ifeq ($(CORE), RISCV64_GENERIC)
CCOMMON_OPT += -march=rv64imafdc -mabi=lp64d
FCOMMON_OPT += -march=rv64imafdc -mabi=lp64d
endif
ifeq ($(CORE), U74)
CCOMMON_OPT += -march=rv64imafdc_zba_zbb -mabi=lp64d -mtune=sifive-u74
FCOMMON_OPT += -march=rv64imafdc_zba_zbb -mabi=lp64d -mtune=sifive-u74
endif
+8 -8
View File
@@ -3,17 +3,17 @@
#
# This library's version
VERSION = 0.3.33.dev
VERSION = 0.3.34
# 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
#
# If you set this prefix, the library name will be lib$(LIBNAMEPREFIX)openblas.a
# and lib$(LIBNAMEPREFIX)openblas.so, with a matching soname in the shared library
#
# LIBNAMEPREFIX = scipy
# If you set the suffix, the library name will be libopenblas_$(LIBNAMESUFFIX).a
# and libopenblas_$(LIBNAMESUFFIX).so. Meanwhile, the soname in shared library
# is libopenblas_$(LIBNAMESUFFIX).so.0.
# LIBNAMESUFFIX = omp
# If you set the suffix, the library name will be libopenblas$(LIBNAMESUFFIX).a
# and libopenblas$(LIBNAMESUFFIX).so. Meanwhile, the soname in shared library
# is libopenblas$(LIBNAMESUFFIX).so.0.
# LIBNAMESUFFIX = _omp
# You can specify the target architecture, otherwise it's
# automatically detected.
+4
View File
@@ -18,6 +18,10 @@ HOSTARCH := $(shell uname -m)
ifeq ($(HOSTARCH), amd64)
HOSTARCH=x86_64
endif
ifeq ($(HOSTARCH), i386)
HOSTARCH=x86
override BINARY=32
endif
# Catch conflicting usage of ARCH in some BSD environments
ifeq ($(ARCH), amd64)
+1
View File
@@ -128,6 +128,7 @@ RISCV64_ZVL128B
C910V
x280
RISCV64_ZVL256B
U74 (e.g. SiFive U74 / StarFive JH7110 / VisionFive 2)
11.LOONGARCH64:
// LOONGSONGENERIC/LOONGSON2K1000/LOONGSON3R5 are legacy names,
+19 -5
View File
@@ -59,6 +59,20 @@ typedef void (*openblas_dojob_callback)(int thread_num, void *jobdata, int dojob
typedef void (*openblas_threads_callback)(int sync, openblas_dojob_callback dojob, int numjobs, size_t jobdata_elsize, void *jobdata, int dojob_data);
void openblas_set_threads_callback_function(openblas_threads_callback callback);
/* Replace the XERBLA handler for this OpenBLAS instance and return the
* previous handler. Passing NULL restores the default. Callbacks may run
* concurrently and must be thread-safe. The name and info pointers are valid
* only during the callback; name spans name_length bytes and need not be
* NUL-terminated. Replacement is thread-safe but does not wait for in-flight
* calls, so the previous handler must remain loaded until they complete. */
#ifndef OPENBLAS_XERBLA_HANDLER_DEFINED
#define OPENBLAS_XERBLA_HANDLER_DEFINED
typedef void (*openblas_xerbla_handler)(const char *name,
const blasint *info,
size_t name_length);
#endif
openblas_xerbla_handler openblas_set_xerbla(openblas_xerbla_handler handler);
#ifdef OPENBLAS_OS_LINUX
/* Sets thread affinity for OpenBLAS threads. `thread_idx` is in [0, openblas_get_num_threads()-1]. */
int openblas_setaffinity(int thread_idx, size_t cpusetsize, cpu_set_t* cpu_set);
@@ -435,13 +449,13 @@ void cblas_cimatcopy(OPENBLAS_CONST enum CBLAS_ORDER CORDER, OPENBLAS_CONST enum
void cblas_zimatcopy(OPENBLAS_CONST enum CBLAS_ORDER CORDER, OPENBLAS_CONST enum CBLAS_TRANSPOSE CTRANS, OPENBLAS_CONST blasint crows, OPENBLAS_CONST blasint ccols, OPENBLAS_CONST double* calpha, double* a,
OPENBLAS_CONST blasint clda, OPENBLAS_CONST blasint cldb);
void cblas_sgeadd(OPENBLAS_CONST enum CBLAS_ORDER CORDER,OPENBLAS_CONST blasint crows, OPENBLAS_CONST blasint ccols, OPENBLAS_CONST float calpha, OPENBLAS_CONST float *a, OPENBLAS_CONST blasint clda, OPENBLAS_CONST float cbeta,
float *c, OPENBLAS_CONST blasint cldc);
void cblas_dgeadd(OPENBLAS_CONST enum CBLAS_ORDER CORDER,OPENBLAS_CONST blasint crows, OPENBLAS_CONST blasint ccols, OPENBLAS_CONST double calpha, OPENBLAS_CONST double *a, OPENBLAS_CONST blasint clda, OPENBLAS_CONST double cbeta,
void cblas_sgeadd(OPENBLAS_CONST enum CBLAS_ORDER CORDER,OPENBLAS_CONST enum CBLAS_TRANSPOSE CTRANS_A,OPENBLAS_CONST enum CBLAS_TRANSPOSE CTRANS_C,OPENBLAS_CONST blasint crows, OPENBLAS_CONST blasint ccols, OPENBLAS_CONST float calpha, OPENBLAS_CONST float *a, OPENBLAS_CONST blasint clda,OPENBLAS_CONST float cbeta, float *c,
OPENBLAS_CONST blasint cldc);
void cblas_dgeadd(OPENBLAS_CONST enum CBLAS_ORDER CORDER,OPENBLAS_CONST enum CBLAS_TRANSPOSE CTRANS_A,OPENBLAS_CONST enum CBLAS_TRANSPOSE CTRANS_C,OPENBLAS_CONST blasint crows, OPENBLAS_CONST blasint ccols, OPENBLAS_CONST double calpha, OPENBLAS_CONST double *a, OPENBLAS_CONST blasint clda, OPENBLAS_CONST double cbeta,
double *c, OPENBLAS_CONST blasint cldc);
void cblas_cgeadd(OPENBLAS_CONST enum CBLAS_ORDER CORDER,OPENBLAS_CONST blasint crows, OPENBLAS_CONST blasint ccols, OPENBLAS_CONST float *calpha, OPENBLAS_CONST float *a, OPENBLAS_CONST blasint clda, OPENBLAS_CONST float *cbeta,
void cblas_cgeadd(OPENBLAS_CONST enum CBLAS_ORDER CORDER,OPENBLAS_CONST enum CBLAS_TRANSPOSE CTRANS_A,OPENBLAS_CONST enum CBLAS_TRANSPOSE CTRANS_C,OPENBLAS_CONST blasint crows, OPENBLAS_CONST blasint ccols, OPENBLAS_CONST float *calpha, OPENBLAS_CONST float *a, OPENBLAS_CONST blasint clda, OPENBLAS_CONST float *cbeta,
float *c, OPENBLAS_CONST blasint cldc);
void cblas_zgeadd(OPENBLAS_CONST enum CBLAS_ORDER CORDER,OPENBLAS_CONST blasint crows, OPENBLAS_CONST blasint ccols, OPENBLAS_CONST double *calpha, OPENBLAS_CONST double *a, OPENBLAS_CONST blasint clda, OPENBLAS_CONST double *cbeta,
void cblas_zgeadd(OPENBLAS_CONST enum CBLAS_ORDER CORDER,OPENBLAS_CONST enum CBLAS_TRANSPOSE CTRANS_A,OPENBLAS_CONST enum CBLAS_TRANSPOSE CTRANS_C,OPENBLAS_CONST blasint crows, OPENBLAS_CONST blasint ccols, OPENBLAS_CONST double *calpha, OPENBLAS_CONST double *a, OPENBLAS_CONST blasint clda, OPENBLAS_CONST double *cbeta,
double *c, OPENBLAS_CONST blasint cldc);
void cblas_sgemm_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,
+3
View File
@@ -428,6 +428,9 @@ endif()
if (${CORE} STREQUAL RISCV64_GENERIC)
set (CCOMMON_OPT "${CCOMMON_OPT} -march=rv64imafdc -mabi=lp64d")
endif()
if (${CORE} STREQUAL U74)
set (CCOMMON_OPT "${CCOMMON_OPT} -march=rv64imafdc_zba_zbb -mabi=lp64d -mtune=sifive-u74")
endif()
if (${CORE} STREQUAL x280)
set (CCOMMON_OPT "${CCOMMON_OPT} -march=rv64imafdcv_zba_zbb_zfh_zvl512b -mabi=lp64d")
endif()
+9
View File
@@ -1504,6 +1504,15 @@ endif ()
"#define DTB_DEFAULT_ENTRIES 128\n"
"#define DTB_SIZE 4096\n"
"#define L2_ASSOCIATIVE 4\n")
elseif ("${TCORE}" STREQUAL "U74")
file(APPEND ${TARGET_CONF_TEMP}
"#define L1_DATA_SIZE 32768\n"
"#define L1_DATA_LINESIZE 64\n"
"#define L2_SIZE 2097152\n"
"#define L2_LINESIZE 64 \n"
"#define DTB_DEFAULT_ENTRIES 128\n"
"#define DTB_SIZE 4096\n"
"#define L2_ASSOCIATIVE 16\n")
elseif ("${TCORE}" STREQUAL "WASM128_GENERIC")
file(APPEND ${TARGET_CONF_TEMP}
"#define L1_DATA_SIZE 32768\n"
+5 -2
View File
@@ -409,6 +409,9 @@ if (${TARGET} STREQUAL NEOVERSEV1)
if (${TARGET} STREQUAL RISCV64_GENERIC)
set (KERNEL_DEFINITIONS "${KERNEL_DEFINITIONS} -march=rv64imafdc -mabi=lp64d")
endif()
if (${TARGET} STREQUAL U74)
set (KERNEL_DEFINITIONS "${KERNEL_DEFINITIONS} -march=rv64imafdc_zba_zbb -mabi=lp64d -mtune=sifive-u74")
endif()
if (${TARGET} STREQUAL x280)
set (KERNEL_DEFINITIONS "${KERNEL_DEFINITIONS} -march=rv64imafdcv_zba_zbb_zfh_zvl512b -mabi=lp64d")
endif()
@@ -648,8 +651,8 @@ endif()
set(LIBPREFIX "lib${LIBNAMEPREFIX}openblas")
if (DEFINED LIBNAMESUFFIX)
set(LIBPREFIX "${LIBNAMEPREFIX}_${LIBNAMESUFFIX}")
if (DEFINED LIBNAMESUFFIX AND NOT "${LIBNAMESUFFIX}" STREQUAL "")
set(LIBPREFIX "lib${LIBNAMEPREFIX}openblas${LIBNAMESUFFIX}")
endif ()
if (NOT DEFINED SYMBOLPREFIX)
+20
View File
@@ -880,6 +880,26 @@ typedef struct {
#endif
#include "common_interface.h"
/* Internal declaration of the public C XERBLA callback API. Keep this out of
* common_interface.h, whose contents are copied verbatim into f77blas.h and
* are not adjusted for SYMBOLPREFIX/SYMBOLSUFFIX by the CMake build. */
#ifndef ASSEMBLER
#ifdef __cplusplus
extern "C" {
#endif
#ifndef OPENBLAS_XERBLA_HANDLER_DEFINED
#define OPENBLAS_XERBLA_HANDLER_DEFINED
typedef void (*openblas_xerbla_handler)(const char *name,
const blasint *info,
size_t name_length);
#endif
openblas_xerbla_handler openblas_set_xerbla(openblas_xerbla_handler handler);
#ifdef __cplusplus
}
#endif
#endif
#ifdef SANITY_CHECK
#include "common_reference.h"
#endif
+4 -4
View File
@@ -801,10 +801,10 @@ void BLASFUNC(dimatcopy) (char *, char *, blasint *, blasint *, double *, do
void BLASFUNC(cimatcopy) (char *, char *, blasint *, blasint *, float *, float *, blasint *, blasint *);
void BLASFUNC(zimatcopy) (char *, char *, blasint *, blasint *, double *, double *, blasint *, blasint *);
void BLASFUNC(sgeadd) (blasint *, blasint *, float *, float *, blasint *, float *, float *, blasint*);
void BLASFUNC(dgeadd) (blasint *, blasint *, double *, double *, blasint *, double *, double *, blasint*);
void BLASFUNC(cgeadd) (blasint *, blasint *, float *, float *, blasint *, float *, float *, blasint*);
void BLASFUNC(zgeadd) (blasint *, blasint *, double *, double *, blasint *, double *, double *, blasint*);
void BLASFUNC(sgeadd) (blasint *, blasint *, float *, float *, blasint *, float *, float *, blasint*,char*, char*);
void BLASFUNC(dgeadd) (blasint *, blasint *, double *, double *, blasint *, double *, double *, blasint*,char *, char *);
void BLASFUNC(cgeadd) (blasint *, blasint *, float *, float *, blasint *, float *, float *, blasint*,char *, char *);
void BLASFUNC(zgeadd) (blasint *, blasint *, double *, double *, blasint *, double *, double *, blasint*,char *, char *);
#ifdef __cplusplus
+4 -4
View File
@@ -2050,10 +2050,10 @@ int zimatcopy_k_rnc(BLASLONG, BLASLONG, double, double, double *, BLASLONG);
int zimatcopy_k_ctc(BLASLONG, BLASLONG, double, double, double *, BLASLONG);
int zimatcopy_k_rtc(BLASLONG, BLASLONG, double, double, double *, BLASLONG);
int sgeadd_k(BLASLONG, BLASLONG, float, float*, BLASLONG, float, float *, BLASLONG);
int dgeadd_k(BLASLONG, BLASLONG, double, double*, BLASLONG, double, double *, BLASLONG);
int cgeadd_k(BLASLONG, BLASLONG, float, float, float*, BLASLONG, float, float, float *, BLASLONG);
int zgeadd_k(BLASLONG, BLASLONG, double,double, double*, BLASLONG, double, double, double *, BLASLONG);
int sgeadd_k(BLASLONG, BLASLONG, float, float*, BLASLONG, float, float *, BLASLONG,BLASLONG,BLASLONG);
int dgeadd_k(BLASLONG, BLASLONG, double, double*, BLASLONG, double, double *, BLASLONG,BLASLONG,BLASLONG);
int cgeadd_k(BLASLONG, BLASLONG, float, float, float*, BLASLONG, float, float, float *, BLASLONG,BLASLONG,BLASLONG);
int zgeadd_k(BLASLONG, BLASLONG, double,double, double*, BLASLONG, double, double, double *, BLASLONG,BLASLONG,BLASLONG);
int sgemm_batch_thread(blas_arg_t * queue, BLASLONG nums);
int dgemm_batch_thread(blas_arg_t * queue, BLASLONG nums);
+1 -1
View File
@@ -2712,7 +2712,7 @@
#ifndef ASSEMBLER
#if !defined(DYNAMIC_ARCH) \
&& (defined(ARCH_X86) || defined(ARCH_X86_64) || defined(ARCH_IA64) || defined(ARCH_MIPS64) || defined(ARCH_ARM64) \
|| defined(ARCH_LOONGARCH64) || defined(ARCH_E2K) || defined(ARCH_ALPHA))
|| defined(ARCH_LOONGARCH64) || defined(ARCH_E2K) || defined(ARCH_ALPHA) || defined(ARCH_RISCV64))
extern BLASLONG gemm_offset_a;
extern BLASLONG gemm_offset_b;
extern BLASLONG bgemm_p;
+4 -4
View File
@@ -1256,16 +1256,16 @@ int (*shgemv_t) (BLASLONG, BLASLONG, float, hfloat16 *, BLASLONG, hfloat16 *, BL
#endif
#if (BUILD_SINGLE==1)
int (*sgeadd_k) (BLASLONG, BLASLONG, float, float *, BLASLONG, float, float *, BLASLONG);
int (*sgeadd_k) (BLASLONG, BLASLONG, float, float *, BLASLONG, float, float *, BLASLONG, BLASLONG, BLASLONG);
#endif
#if (BUILD_DOUBLE==1)
int (*dgeadd_k) (BLASLONG, BLASLONG, double, double *, BLASLONG, double, double *, BLASLONG);
int (*dgeadd_k) (BLASLONG, BLASLONG, double, double *, BLASLONG, double, double *, BLASLONG, BLASLONG, BLASLONG);
#endif
#if (BUILD_COMPLEX==1)
int (*cgeadd_k) (BLASLONG, BLASLONG, float, float, float *, BLASLONG, float, float, float *, BLASLONG);
int (*cgeadd_k) (BLASLONG, BLASLONG, float, float, float *, BLASLONG, float, float, float *, BLASLONG, BLASLONG, BLASLONG);
#endif
#if (BUILD_COMPLEX16==1)
int (*zgeadd_k) (BLASLONG, BLASLONG, double, double, double *, BLASLONG, double, double, double *, BLASLONG);
int (*zgeadd_k) (BLASLONG, BLASLONG, double, double, double *, BLASLONG, double, double, double *, BLASLONG, BLASLONG, BLASLONG);
#endif
} gotoblas_t;
+9
View File
@@ -138,10 +138,19 @@ typedef struct blas_queue {
extern int blas_server_avail;
extern int blas_omp_number_max;
extern int blas_omp_threads_local;
extern int blas_is_num_threads_set_explicitly;
static __inline int num_cpu_avail(int level) {
#ifdef USE_OPENMP
/* If the user explicitly called openblas_set_num_threads(),
respect that setting instead of overriding it with
`omp_get_max_threads()` below (which is to get a default
in case the user hasn't made an explicit choice). */
if (blas_is_num_threads_set_explicitly) {
return blas_cpu_number;
}
int openmp_nthreads;
openmp_nthreads=omp_get_max_threads();
if (omp_in_parallel()) openmp_nthreads = blas_omp_threads_local;
+23 -8
View File
@@ -75,13 +75,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define CPU_x280 2
#define CPU_RISCV64_ZVL256B 3
#define CPU_RISCV64_ZVL128B 4
#define CPU_U74 5
static char *cpuname[] = {
"RISCV64_GENERIC",
"C910V",
"x280",
"CPU_RISCV64_ZVL256B",
"CPU_RISCV64_ZVL128B"
"CPU_RISCV64_ZVL128B",
"U74"
};
static char *cpuname_lower[] = {
@@ -89,15 +91,17 @@ static char *cpuname_lower[] = {
"c910v",
"x280",
"riscv64_zvl256b",
"riscv64_zvl128b"
"riscv64_zvl128b",
"u74"
};
int detect(void){
#ifdef __linux
FILE *infile;
char buffer[512],isa_buffer[512],model_buffer[512];
char buffer[512],isa_buffer[512],model_buffer[512], uarch_buffer[512];
const char* check_c910_str = "T-HEAD C910";
char *pmodel = NULL, *pisa = NULL;
const char* check_u74_str = "sifive,u74";
char *pmodel = NULL, *pisa = NULL, *puarch = NULL;
infile = fopen("/proc/cpuinfo", "r");
if (!infile)
@@ -110,6 +114,13 @@ int detect(void){
pmodel++;
}
if(!strncmp(buffer, "uarch", 5)){
strcpy(uarch_buffer, buffer);
puarch = strchr(uarch_buffer, ':');
if (puarch)
puarch++;
}
if(!strncmp(buffer, "isa", 3)){
strcpy(isa_buffer, buffer);
pisa = strchr(isa_buffer, '4');
@@ -120,12 +131,16 @@ int detect(void){
fclose(infile);
if (!pmodel || !pisa)
if ((!pmodel && !puarch) || !pisa)
return(CPU_GENERIC);
if (strstr(pmodel, check_c910_str) && strchr(pisa, 'v'))
return CPU_C910V;
if (pmodel) {
if (strstr(pmodel, check_c910_str) && strchr(pisa, 'v'))
return CPU_C910V;
} else if (puarch) {
if (strstr(puarch, check_u74_str) && !strchr(pisa, 'v'))
return CPU_U74;
}
return CPU_GENERIC;
#endif
+1
View File
@@ -18,6 +18,7 @@ if(WIN32)
FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/test_cblas_helper.ps1
"$ErrorActionPreference = \"Stop\"\n"
"Get-Content $args[1] | & $args[0]\n"
"exit $LASTEXITCODE\n"
)
set(test_helper powershell -ExecutionPolicy Bypass "${CMAKE_CURRENT_BINARY_DIR}/test_cblas_helper.ps1")
else()
+6 -15
View File
@@ -4,21 +4,14 @@
#include "cblas_test.h"
int cblas_ok, cblas_lerr, cblas_info;
int link_xerbla=TRUE;
char *cblas_rout;
#ifdef F77_Char
void F77_xerbla(F77_Char F77_srname, void *vinfo);
#else
void F77_xerbla(char *srname, void *vinfo);
#endif
void chkxer(void) {
extern int cblas_ok, cblas_lerr, cblas_info;
extern int link_xerbla;
extern char *cblas_rout;
if (cblas_lerr == 1 ) {
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %d NOT DETECTED BY %s *****\n", cblas_info, cblas_rout);
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %lld NOT DETECTED BY %s *****\n",
(long long)cblas_info, cblas_rout);
cblas_ok = 0 ;
}
cblas_lerr = 1 ;
@@ -36,11 +29,7 @@ void F77_c2chke(char *rout) {
extern int RowMajorStrg;
extern char *cblas_rout;
if (link_xerbla) /* call these first to link */
{
cblas_xerbla(cblas_info,cblas_rout,"");
F77_xerbla(cblas_rout,&cblas_info);
}
cblas_test_set_xerbla();
cblas_ok = TRUE ;
cblas_lerr = PASSED ;
@@ -821,6 +810,8 @@ void F77_c2chke(char *rout) {
}
if (cblas_ok == TRUE)
printf(" %-12s PASSED THE TESTS OF ERROR-EXITS\n", cblas_rout);
else
else {
printf("******* %s FAILED THE TESTS OF ERROR-EXITS *******\n",cblas_rout);
cblas_test_fail();
}
}
+6 -15
View File
@@ -4,21 +4,14 @@
#include "cblas_test.h"
int cblas_ok, cblas_lerr, cblas_info;
int link_xerbla=TRUE;
char *cblas_rout;
#ifdef F77_Char
void F77_xerbla(F77_Char F77_srname, void *vinfo);
#else
void F77_xerbla(char *srname, void *vinfo);
#endif
void chkxer(void) {
extern int cblas_ok, cblas_lerr, cblas_info;
extern int link_xerbla;
extern char *cblas_rout;
if (cblas_lerr == 1 ) {
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %d NOT DETECTED BY %s *****\n", cblas_info, cblas_rout);
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %lld NOT DETECTED BY %s *****\n",
(long long)cblas_info, cblas_rout);
cblas_ok = 0 ;
}
cblas_lerr = 1 ;
@@ -39,11 +32,7 @@ void F77_c3chke(char * rout) {
cblas_ok = TRUE ;
cblas_lerr = PASSED ;
if (link_xerbla) /* call these first to link */
{
cblas_xerbla(cblas_info,cblas_rout,"");
F77_xerbla(cblas_rout,&cblas_info);
}
cblas_test_set_xerbla();
if (strncmp( sf,"cblas_cgemm" ,11)==0) {
@@ -1703,6 +1692,8 @@ void F77_c3chke(char * rout) {
if (cblas_ok == 1 )
printf(" %-12s PASSED THE TESTS OF ERROR-EXITS\n", cblas_rout);
else
else {
printf("***** %s FAILED THE TESTS OF ERROR-EXITS *******\n",cblas_rout);
cblas_test_fail();
}
}
+6 -15
View File
@@ -4,21 +4,14 @@
#include "cblas_test.h"
int cblas_ok, cblas_lerr, cblas_info;
int link_xerbla=TRUE;
char *cblas_rout;
#ifdef F77_Char
void F77_xerbla(F77_Char F77_srname, void *vinfo);
#else
void F77_xerbla(char *srname, void *vinfo);
#endif
void chkxer(void) {
extern int cblas_ok, cblas_lerr, cblas_info;
extern int link_xerbla;
extern char *cblas_rout;
if (cblas_lerr == 1 ) {
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %d NOT DETECTED BY %s *****\n", cblas_info, cblas_rout);
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %lld NOT DETECTED BY %s *****\n",
(long long)cblas_info, cblas_rout);
cblas_ok = 0 ;
}
cblas_lerr = 1 ;
@@ -39,11 +32,7 @@ void F77_c3chke(char * rout) {
cblas_ok = TRUE ;
cblas_lerr = PASSED ;
if (link_xerbla) /* call these first to link */
{
cblas_xerbla(cblas_info,cblas_rout,"");
F77_xerbla(cblas_rout,&cblas_info);
}
cblas_test_set_xerbla();
if (strncmp( sf,"cblas_cgemm3m" ,13)==0) {
@@ -1931,6 +1920,8 @@ void F77_c3chke(char * rout) {
if (cblas_ok == 1 )
printf(" %-12s PASSED THE TESTS OF ERROR-EXITS\n", cblas_rout);
else
else {
printf("***** %s FAILED THE TESTS OF ERROR-EXITS *******\n",cblas_rout);
cblas_test_fail();
}
}
+6 -15
View File
@@ -4,21 +4,14 @@
#include "cblas_test.h"
int cblas_ok, cblas_lerr, cblas_info;
int link_xerbla=TRUE;
char *cblas_rout;
#ifdef F77_Char
void F77_xerbla(F77_Char F77_srname, void *vinfo);
#else
void F77_xerbla(char *srname, void *vinfo);
#endif
void chkxer(void) {
extern int cblas_ok, cblas_lerr, cblas_info;
extern int link_xerbla;
extern char *cblas_rout;
if (cblas_lerr == 1 ) {
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %d NOT DETECTED BY %s *****\n", cblas_info, cblas_rout);
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %lld NOT DETECTED BY %s *****\n",
(long long)cblas_info, cblas_rout);
cblas_ok = 0 ;
}
cblas_lerr = 1 ;
@@ -34,11 +27,7 @@ void F77_d2chke(char *rout) {
extern int RowMajorStrg;
extern char *cblas_rout;
if (link_xerbla) /* call these first to link */
{
cblas_xerbla(cblas_info,cblas_rout,"");
F77_xerbla(cblas_rout,&cblas_info);
}
cblas_test_set_xerbla();
cblas_ok = TRUE ;
cblas_lerr = PASSED ;
@@ -784,6 +773,8 @@ void F77_d2chke(char *rout) {
}
if (cblas_ok == TRUE)
printf(" %-12s PASSED THE TESTS OF ERROR-EXITS\n", cblas_rout);
else
else {
printf("******* %s FAILED THE TESTS OF ERROR-EXITS *******\n",cblas_rout);
cblas_test_fail();
}
}
+6 -15
View File
@@ -4,21 +4,14 @@
#include "cblas_test.h"
int cblas_ok, cblas_lerr, cblas_info;
int link_xerbla=TRUE;
char *cblas_rout;
#ifdef F77_Char
void F77_xerbla(F77_Char F77_srname, void *vinfo);
#else
void F77_xerbla(char *srname, void *vinfo);
#endif
void chkxer(void) {
extern int cblas_ok, cblas_lerr, cblas_info;
extern int link_xerbla;
extern char *cblas_rout;
if (cblas_lerr == 1 ) {
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %d NOT DETECTED BY %s *****\n", cblas_info, cblas_rout);
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %lld NOT DETECTED BY %s *****\n",
(long long)cblas_info, cblas_rout);
cblas_ok = 0 ;
}
cblas_lerr = 1 ;
@@ -34,11 +27,7 @@ void F77_d3chke(char *rout) {
extern int RowMajorStrg;
extern char *cblas_rout;
if (link_xerbla) /* call these first to link */
{
cblas_xerbla(cblas_info,cblas_rout,"");
F77_xerbla(cblas_rout,&cblas_info);
}
cblas_test_set_xerbla();
cblas_ok = TRUE ;
cblas_lerr = PASSED ;
@@ -1266,6 +1255,8 @@ void F77_d3chke(char *rout) {
}
if (cblas_ok == TRUE )
printf(" %-12s PASSED THE TESTS OF ERROR-EXITS\n", cblas_rout);
else
else {
printf("***** %s FAILED THE TESTS OF ERROR-EXITS *******\n",cblas_rout);
cblas_test_fail();
}
}
+6 -15
View File
@@ -4,21 +4,14 @@
#include "cblas_test.h"
int cblas_ok, cblas_lerr, cblas_info;
int link_xerbla=TRUE;
char *cblas_rout;
#ifdef F77_Char
void F77_xerbla(F77_Char F77_srname, void *vinfo);
#else
void F77_xerbla(char *srname, void *vinfo);
#endif
void chkxer(void) {
extern int cblas_ok, cblas_lerr, cblas_info;
extern int link_xerbla;
extern char *cblas_rout;
if (cblas_lerr == 1 ) {
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %d NOT DETECTED BY %s *****\n", cblas_info, cblas_rout);
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %lld NOT DETECTED BY %s *****\n",
(long long)cblas_info, cblas_rout);
cblas_ok = 0 ;
}
cblas_lerr = 1 ;
@@ -34,11 +27,7 @@ void F77_s2chke(char *rout) {
extern int RowMajorStrg;
extern char *cblas_rout;
if (link_xerbla) /* call these first to link */
{
cblas_xerbla(cblas_info,cblas_rout,"");
F77_xerbla(cblas_rout,&cblas_info);
}
cblas_test_set_xerbla();
cblas_ok = TRUE ;
cblas_lerr = PASSED ;
@@ -784,6 +773,8 @@ void F77_s2chke(char *rout) {
}
if (cblas_ok == TRUE)
printf(" %-12s PASSED THE TESTS OF ERROR-EXITS\n", cblas_rout);
else
else {
printf("******* %s FAILED THE TESTS OF ERROR-EXITS *******\n",cblas_rout);
cblas_test_fail();
}
}
+6 -15
View File
@@ -4,21 +4,14 @@
#include "cblas_test.h"
int cblas_ok, cblas_lerr, cblas_info;
int link_xerbla=TRUE;
char *cblas_rout;
#ifdef F77_Char
void F77_xerbla(F77_Char F77_srname, void *vinfo);
#else
void F77_xerbla(char *srname, void *vinfo);
#endif
void chkxer(void) {
extern int cblas_ok, cblas_lerr, cblas_info;
extern int link_xerbla;
extern char *cblas_rout;
if (cblas_lerr == 1 ) {
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %d NOT DETECTED BY %s *****\n", cblas_info, cblas_rout);
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %lld NOT DETECTED BY %s *****\n",
(long long)cblas_info, cblas_rout);
cblas_ok = 0 ;
}
cblas_lerr = 1 ;
@@ -34,11 +27,7 @@ void F77_s3chke(char *rout) {
extern int RowMajorStrg;
extern char *cblas_rout;
if (link_xerbla) /* call these first to link */
{
cblas_xerbla(cblas_info,cblas_rout,"");
F77_xerbla(cblas_rout,&cblas_info);
}
cblas_test_set_xerbla();
cblas_ok = TRUE ;
cblas_lerr = PASSED ;
@@ -1268,6 +1257,8 @@ void F77_s3chke(char *rout) {
}
if (cblas_ok == TRUE )
printf(" %-12s PASSED THE TESTS OF ERROR-EXITS\n", cblas_rout);
else
else {
printf("***** %s FAILED THE TESTS OF ERROR-EXITS *******\n",cblas_rout);
cblas_test_fail();
}
}
+18 -46
View File
@@ -1,4 +1,5 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdarg.h>
#include <string.h>
@@ -8,17 +9,9 @@
void cblas_xerbla(blasint info, char *rout, char *form, ...)
{
extern int cblas_lerr, cblas_info, cblas_ok;
extern int link_xerbla;
extern int RowMajorStrg;
extern char *cblas_rout;
/* Initially, c__3chke will call this routine with
* global variable link_xerbla=1, and F77_xerbla will set link_xerbla=0.
* This is done to fool the linker into loading these subroutines first
* instead of ones in the CBLAS or the legacy BLAS library.
*/
if (link_xerbla) return;
if (cblas_rout != NULL && strcmp(cblas_rout, rout) != 0){
printf("***** XERBLA WAS CALLED WITH SRNAME = <%s> INSTEAD OF <%s> *******\n", rout, cblas_rout);
cblas_ok = FALSE;
@@ -78,44 +71,27 @@ void cblas_xerbla(blasint info, char *rout, char *form, ...)
}
if (info != cblas_info){
printf("***** XERBLA WAS CALLED WITH INFO = %d INSTEAD OF %d in %s *******\n",info, cblas_info, rout);
printf("***** XERBLA WAS CALLED WITH INFO = %lld INSTEAD OF %lld in %s *******\n",
(long long)info, (long long)cblas_info, rout);
cblas_lerr = PASSED;
cblas_ok = FALSE;
} else cblas_lerr = FAILED;
}
#ifdef F77_Char
void F77_xerbla(F77_Char F77_srname, void *vinfo)
#else
void F77_xerbla(char *srname, void *vinfo)
#endif
static void cblas_test_xerbla(const char *srname, const blasint *info,
size_t length)
{
#ifdef F77_Char
char *srname;
#endif
extern int cblas_ok;
char rout[] = {'c','b','l','a','s','_','\0','\0','\0','\0','\0','\0','\0'};
blasint i;
#ifdef F77_Integer
F77_Integer *info=vinfo;
F77_Integer i;
extern F77_Integer link_xerbla;
#else
int *info=vinfo;
int i;
extern int link_xerbla;
#endif
#ifdef F77_Char
srname = F2C_STR(F77_srname, XerblaStrLen);
#endif
/* See the comment in cblas_xerbla() above */
if (link_xerbla)
{
link_xerbla = 0;
if (length < 6) {
printf("***** XERBLA WAS CALLED WITH AN INVALID ROUTINE NAME LENGTH *******\n");
cblas_ok = FALSE;
return;
}
for(i=0; i < 6; i++) rout[i+6] = tolower(srname[i]);
for(i=0; i < 6; i++) rout[i+6] = tolower((unsigned char)srname[i]);
for(i=11; i >= 9; i--) if (rout[i] == ' ') rout[i] = '\0';
/* We increment *info by 1 since the CBLAS interface adds one more
@@ -124,14 +100,10 @@ void F77_xerbla(char *srname, void *vinfo)
cblas_xerbla(*info+1,rout,"");
}
#ifdef USE64BITINT
#undef int
#endif
int BLASFUNC(xerbla)(char *name, blasint *info, blasint length) {
F77_xerbla(name, info);
return 0;
};
void cblas_test_set_xerbla(void) {
openblas_set_xerbla(cblas_test_xerbla);
}
void cblas_test_fail(void) {
exit(EXIT_FAILURE);
}
+6 -15
View File
@@ -4,21 +4,14 @@
#include "cblas_test.h"
int cblas_ok, cblas_lerr, cblas_info;
int link_xerbla=TRUE;
char *cblas_rout;
#ifdef F77_Char
void F77_xerbla(F77_Char F77_srname, void *vinfo);
#else
void F77_xerbla(char *srname, void *vinfo);
#endif
void chkxer(void) {
extern int cblas_ok, cblas_lerr, cblas_info;
extern int link_xerbla;
extern char *cblas_rout;
if (cblas_lerr == 1 ) {
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %d NOT DETECTED BY %s *****\n", cblas_info, cblas_rout);
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %lld NOT DETECTED BY %s *****\n",
(long long)cblas_info, cblas_rout);
cblas_ok = 0 ;
}
cblas_lerr = 1 ;
@@ -36,11 +29,7 @@ void F77_z2chke(char *rout) {
extern int RowMajorStrg;
extern char *cblas_rout;
if (link_xerbla) /* call these first to link */
{
cblas_xerbla(cblas_info,cblas_rout,"");
F77_xerbla(cblas_rout,&cblas_info);
}
cblas_test_set_xerbla();
cblas_ok = TRUE ;
cblas_lerr = PASSED ;
@@ -821,6 +810,8 @@ void F77_z2chke(char *rout) {
}
if (cblas_ok == TRUE)
printf(" %-12s PASSED THE TESTS OF ERROR-EXITS\n", cblas_rout);
else
else {
printf("******* %s FAILED THE TESTS OF ERROR-EXITS *******\n",cblas_rout);
cblas_test_fail();
}
}
+6 -15
View File
@@ -4,21 +4,14 @@
#include "cblas_test.h"
int cblas_ok, cblas_lerr, cblas_info;
int link_xerbla=TRUE;
char *cblas_rout;
#ifdef F77_Char
void F77_xerbla(F77_Char F77_srname, void *vinfo);
#else
void F77_xerbla(char *srname, void *vinfo);
#endif
void chkxer(void) {
extern int cblas_ok, cblas_lerr, cblas_info;
extern int link_xerbla;
extern char *cblas_rout;
if (cblas_lerr == 1 ) {
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %d NOT DETECTED BY %s *****\n", cblas_info, cblas_rout);
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %lld NOT DETECTED BY %s *****\n",
(long long)cblas_info, cblas_rout);
cblas_ok = 0 ;
}
cblas_lerr = 1 ;
@@ -39,11 +32,7 @@ void F77_z3chke(char * rout) {
cblas_ok = TRUE ;
cblas_lerr = PASSED ;
if (link_xerbla) /* call these first to link */
{
cblas_xerbla(cblas_info,cblas_rout,"");
F77_xerbla(cblas_rout,&cblas_info);
}
cblas_test_set_xerbla();
@@ -1705,6 +1694,8 @@ void F77_z3chke(char * rout) {
if (cblas_ok == 1 )
printf(" %-12s PASSED THE TESTS OF ERROR-EXITS\n", cblas_rout);
else
else {
printf("***** %s FAILED THE TESTS OF ERROR-EXITS *******\n",cblas_rout);
cblas_test_fail();
}
}
+6 -15
View File
@@ -4,21 +4,14 @@
#include "cblas_test.h"
int cblas_ok, cblas_lerr, cblas_info;
int link_xerbla=TRUE;
char *cblas_rout;
#ifdef F77_Char
void F77_xerbla(F77_Char F77_srname, void *vinfo);
#else
void F77_xerbla(char *srname, void *vinfo);
#endif
void chkxer(void) {
extern int cblas_ok, cblas_lerr, cblas_info;
extern int link_xerbla;
extern char *cblas_rout;
if (cblas_lerr == 1 ) {
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %d NOT DETECTED BY %s *****\n", cblas_info, cblas_rout);
printf("***** ILLEGAL VALUE OF PARAMETER NUMBER %lld NOT DETECTED BY %s *****\n",
(long long)cblas_info, cblas_rout);
cblas_ok = 0 ;
}
cblas_lerr = 1 ;
@@ -39,11 +32,7 @@ void F77_z3chke(char * rout) {
cblas_ok = TRUE ;
cblas_lerr = PASSED ;
if (link_xerbla) /* call these first to link */
{
cblas_xerbla(cblas_info,cblas_rout,"");
F77_xerbla(cblas_rout,&cblas_info);
}
cblas_test_set_xerbla();
@@ -1935,6 +1924,8 @@ void F77_z3chke(char * rout) {
if (cblas_ok == 1 )
printf(" %-12s PASSED THE TESTS OF ERROR-EXITS\n", cblas_rout);
else
else {
printf("***** %s FAILED THE TESTS OF ERROR-EXITS *******\n",cblas_rout);
cblas_test_fail();
}
}
+3
View File
@@ -30,6 +30,9 @@
#define INVALID -1
#define UNDEFINED -1
void cblas_test_set_xerbla(void);
void cblas_test_fail(void);
typedef struct { float real; float imag; } CBLAS_TEST_COMPLEX;
typedef struct { double real; double imag; } CBLAS_TEST_ZOMPLEX;
+2 -3
View File
@@ -143,9 +143,8 @@ ensures that there are a sufficient number of buffer sets available.
no symbolic linking to variant names (default is `0`)
- `LIBNAMEPREFIX`: prefix that, if given, will be inserted in the library name
before `openblas` (e.g., `xxx` will result in `libxxxopenblas.so`)
- `LIBNAMESUFFIX`: suffix that, if given, will be inserted in the library name
after `openblas`, separated by an underscore (e.g., `yyy` will result in
`libopenblas_yyy.so`)
- `LIBNAMESUFFIX`: suffix that, if given, will be appended to the library name
after `openblas` (e.g., `_yyy` will result in `libopenblas_yyy.so`)
- `SYMBOLPREFIX`: prefix that, if given, will be added to all symbol names
*and* to the library name
- `SYMBOLSUFFIX`: suffix that, if given, will be added to all symbol names
+4
View File
@@ -47,3 +47,7 @@ BLAS-like and conversion functions for `hfloat16` (available when OpenBLAS was c
* `int openblas_set_affinity(int thread_index, size_t cpusetsize, cpu_set_t *cpuset)` sets the CPU affinity mask of the given thread
to the provided cpuset. Only available on Linux, with semantics identical to `pthread_setaffinity_np`.
* `openblas_set_thread_callback_function` overrides the default multithreading backend with the provided argument
* `openblas_set_xerbla(openblas_xerbla_handler handler)` replaces the XERBLA handler for the current OpenBLAS
instance and returns the previous handler; passing `NULL` restores the default. Callbacks may be invoked concurrently
and therefore must be thread-safe. `name` is valid for `name_length` bytes during the callback and need not be
NUL-terminated. On ELF platforms, an application-provided strong `xerbla` symbol bypasses the registered handler.
+1 -1
View File
@@ -71,7 +71,7 @@
static int tpmv_kernel(blas_arg_t *args, BLASLONG *range_m, BLASLONG *range_n, FLOAT *dummy1, FLOAT *buffer, BLASLONG pos){
FLOAT *a, *x, *y;
volatile FLOAT *a, *x, *y;
BLASLONG incx;
BLASLONG m_from, m_to;
+1 -1
View File
@@ -47,7 +47,7 @@ int CNAME(BLASLONG m, BLASLONG n, BLASLONG k, FLOAT alpha_r,
BLASLONG i, j;
BLASLONG loop;
FLOAT subbuffer[GEMM_UNROLL_MN * GEMM_UNROLL_MN * COMPSIZE];
volatile FLOAT subbuffer[GEMM_UNROLL_MN * GEMM_UNROLL_MN * COMPSIZE];
if (m + offset < 0) {
#ifndef LOWER
+5 -4
View File
@@ -70,6 +70,7 @@
int blas_server_avail = 0;
int blas_omp_number_max = 0;
int blas_omp_threads_local = 1;
int blas_is_num_threads_set_explicitly = 0; // tracks whether the user called openblas_set_num_threads()
extern int openblas_omp_adaptive_env(void);
@@ -118,7 +119,7 @@ void goto_set_num_threads(int num_threads) {
}
void openblas_set_num_threads(int num_threads) {
blas_is_num_threads_set_explicitly = 1;
goto_set_num_threads(num_threads);
}
@@ -141,7 +142,7 @@ extern int openblas_omp_num_threads_env(void);
if(blas_omp_number_max <= 0)
blas_omp_number_max= openblas_omp_num_threads_env();
if (blas_omp_number_max <= 0)
if (blas_omp_number_max <= 0)
blas_omp_number_max=MAX_CPU_NUMBER;
#else
blas_omp_number_max = omp_get_max_threads();
@@ -361,14 +362,14 @@ static void exec_threads(int thread_num, blas_queue_t *queue, int buf_index){
#ifdef BUILD_COMPLEX16
sb = (void *)(((BLASLONG)sa + ((ZGEMM_P * ZGEMM_Q * 2 * sizeof(double)
+ GEMM_ALIGN) & ~GEMM_ALIGN)) + GEMM_OFFSET_B);
#else
#else
fprintf(stderr,"UNHANDLED COMPLEX16\n");
#endif
} else if ((queue -> mode & BLAS_PREC) == BLAS_SINGLE) {
#ifdef BUILD_COMPLEX
sb = (void *)(((BLASLONG)sa + ((CGEMM_P * CGEMM_Q * 2 * sizeof(float)
+ GEMM_ALIGN) & ~GEMM_ALIGN)) + GEMM_OFFSET_B);
#else
#else
fprintf(stderr,"UNHANDLED COMPLEX\n");
#endif
} else {
+2 -2
View File
@@ -1220,7 +1220,7 @@ UNLOCK_COMMAND(&alloc_lock);
if (!blas_num_threads) blas_cpu_number = blas_get_cpu_number();
#endif
#if defined(ARCH_X86) || defined(ARCH_X86_64) || defined(ARCH_IA64) || defined(ARCH_MIPS64) || defined(ARCH_ARM64) || defined(ARCH_LOONGARCH64)
#if defined(ARCH_X86) || defined(ARCH_X86_64) || defined(ARCH_IA64) || defined(ARCH_MIPS64) || defined(ARCH_ARM64) || defined(ARCH_LOONGARCH64) || defined(ARCH_RISCV64)
#ifndef DYNAMIC_ARCH
blas_set_parameter();
#endif
@@ -2822,7 +2822,7 @@ void *blas_memory_alloc(int procpos){
if (!blas_num_threads) blas_cpu_number = blas_get_cpu_number();
#endif
#if defined(ARCH_X86) || defined(ARCH_X86_64) || defined(ARCH_IA64) || defined(ARCH_MIPS64) || defined(ARCH_ARM64) || defined(ARCH_LOONGARCH64)
#if defined(ARCH_X86) || defined(ARCH_X86_64) || defined(ARCH_IA64) || defined(ARCH_MIPS64) || defined(ARCH_ARM64) || defined(ARCH_LOONGARCH64) || defined(ARCH_RISCV64)
#ifndef DYNAMIC_ARCH
blas_set_parameter();
#endif
+50
View File
@@ -902,3 +902,53 @@ void blas_set_parameter(void)
}
#endif
#if defined(ARCH_RISCV64)
#include <stdio.h>
/* RISC-V has no architectural cache-size query (cf. x86 CPUID / LoongArch
CPUCFG), so read the L2 (level 2, unified) size from Linux sysfs and fall
back to 512 KB. Returns the L2 size in kilobytes. */
int get_L2_size(void) {
int size = 0;
#if defined(OS_LINUX) || defined(OS_ANDROID)
int idx;
for (idx = 0; idx <= 4; idx++) {
char path[80]; FILE *fp; int level = 0; long val = 0; char unit = 0;
snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu0/cache/index%d/level", idx);
fp = fopen(path, "r"); if (fp == NULL) continue;
if (fscanf(fp, "%d", &level) != 1) { fclose(fp); continue; }
fclose(fp); if (level != 2) continue;
snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu0/cache/index%d/size", idx);
fp = fopen(path, "r"); if (fp == NULL) continue;
if (fscanf(fp, "%ld%c", &val, &unit) >= 1) {
if (unit == 'M' || unit == 'm') val *= 1024;
if (unit == 'G' || unit == 'g') val *= 1024 * 1024;
size = (int)val;
}
fclose(fp); if (size > 0) break;
}
#endif
if (size <= 0) size = 512;
return size;
}
void blas_set_parameter(void) {
#if defined(SGEMM_DEFAULT_P_BASE)
/* Scale each precision's packed-A dimension P from the detected L2, relative
to the size the active core's base blocking targets (RISCV_L2_REFERENCE_KB).
The bases come from the core's own param.h block, so this is not tied to any
single core; Q and R keep their param.h defaults. */
int l2 = get_L2_size(); /* KB */
int scale = l2 / RISCV_L2_REFERENCE_KB;
if (scale < 1) scale = 1;
if (scale > 4) scale = 4;
sgemm_p = SGEMM_DEFAULT_P_BASE * scale;
dgemm_p = DGEMM_DEFAULT_P_BASE * scale;
cgemm_p = CGEMM_DEFAULT_P_BASE * scale;
zgemm_p = ZGEMM_DEFAULT_P_BASE * scale;
#endif
}
#endif
+59 -21
View File
@@ -36,8 +36,10 @@
/* or implied, of The University of Texas at Austin. */
/*********************************************************************/
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#if defined(OS_WINDOWS) && (defined(__MINGW32__) || defined(__MINGW64__))
@@ -46,31 +48,67 @@
#define printf _cprintf
#endif
#ifdef INTERFACE64
#define MSGFMT " ** On entry to %6s parameter number %2ld had an illegal value\n"
#else
#define MSGFMT " ** On entry to %6s parameter number %2d had an illegal value\n"
#endif
#define MSGFMT " ** On entry to %6.*s parameter number %2lld had an illegal value\n"
static size_t openblas_xerbla_name_length(const char *message,
blasint length) {
const char *terminator;
if (message == NULL || length <= 0) return 0;
terminator = memchr(message, '\0', (size_t)length);
if (terminator != NULL) return (size_t)(terminator - message);
return (size_t)length;
}
static void openblas_xerbla_default(const char *message, const blasint *info,
size_t length) {
int precision = length > INT_MAX ? INT_MAX : (int)length;
printf(MSGFMT, precision, message == NULL ? "" : message,
(long long)*info);
}
static openblas_xerbla_handler openblas_xerbla = openblas_xerbla_default;
static volatile BLASULONG openblas_xerbla_lock = 0;
openblas_xerbla_handler
openblas_set_xerbla(openblas_xerbla_handler handler) {
openblas_xerbla_handler previous;
if (handler == NULL) handler = openblas_xerbla_default;
blas_lock(&openblas_xerbla_lock);
previous = openblas_xerbla;
openblas_xerbla = handler;
blas_unlock(&openblas_xerbla_lock);
return previous;
}
static int openblas_xerbla_dispatch(char *message, blasint *info,
blasint length) {
openblas_xerbla_handler handler;
size_t name_length = openblas_xerbla_name_length(message, length);
blas_lock(&openblas_xerbla_lock);
handler = openblas_xerbla;
blas_unlock(&openblas_xerbla_lock);
handler(message, info, name_length);
return 0;
}
#ifdef __ELF__
int __xerbla(char *message, blasint *info, blasint length){
printf(MSGFMT,
message, *info);
return 0;
int __xerbla(char *message, blasint *info, blasint length) {
return openblas_xerbla_dispatch(message, info, length);
}
int BLASFUNC(xerbla)(char *, blasint *, blasint) __attribute__ ((weak, alias ("__xerbla")));
int BLASFUNC(xerbla)(char *, blasint *, blasint)
__attribute__ ((weak, alias ("__xerbla")));
#else
int BLASFUNC(xerbla)(char *message, blasint *info, blasint length){
printf(MSGFMT,
message, *info);
return 0;
int BLASFUNC(xerbla)(char *message, blasint *info, blasint length) {
return openblas_xerbla_dispatch(message, info, length);
}
#endif
+4
View File
@@ -182,6 +182,7 @@ misc_no_underscore_objs="
openblas_get_config
openblas_get_corename
openblas_set_threads_callback_function
openblas_set_xerbla
"
misc_underscore_objs=""
@@ -4111,10 +4112,13 @@ case "$p1" in
done
for obj in $no_underscore_objs; do
[ "$obj" = "openblas_set_xerbla" ] && continue
printf '\t%s%s%s=%s @%s\n' \
"$symbolprefix" "$obj" "$symbolsuffix" "$obj" "$count"
count=`expr $count + 1`
done
printf '\t%sopenblas_set_xerbla%s=openblas_set_xerbla @%s\n' \
"$symbolprefix" "$symbolsuffix" "$count"
;;
win2khpl)
+3
View File
@@ -178,6 +178,7 @@
openblas_get_config,
openblas_get_corename,
openblas_set_threads_callback_function,
openblas_set_xerbla,
);
@misc_underscore_objs = (
@@ -4053,9 +4054,11 @@ if ($ARGV[0] eq "win2k"){
foreach $objs (@no_underscore_objs) {
next if $objs eq "openblas_set_xerbla";
print "\t",$symbolprefix,$objs,$symbolsuffix,"=$objs"," \@", $count, "\n";
$count ++;
}
print "\t",$symbolprefix,"openblas_set_xerbla",$symbolsuffix,"=openblas_set_xerbla \@",$count,"\n";
exit(0);
}
+14
View File
@@ -1232,6 +1232,20 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#else
#endif
#ifdef FORCE_U74
#define FORCE
#define ARCHITECTURE "RISCV64"
#define SUBARCHITECTURE "U74"
#define SUBDIRNAME "riscv64"
#define ARCHCONFIG "-DU74 " \
"-DL1_DATA_SIZE=32768 -DL1_DATA_LINESIZE=64 " \
"-DL2_SIZE=2097152 -DL2_LINESIZE=64 " \
"-DDTB_DEFAULT_ENTRIES=128 -DDTB_SIZE=4096 -DL2_ASSOCIATIVE=16 "
#define LIBNAME "u74"
#define CORENAME "U74"
#else
#endif
#ifdef FORCE_WASM128_GENERIC
#define FORCE
#define ARCHITECTURE "WASM"
+50 -9
View File
@@ -51,7 +51,7 @@
#ifndef CBLAS
void NAME(blasint *M, blasint *N, FLOAT *ALPHA, FLOAT *a, blasint *LDA,
FLOAT *BETA, FLOAT *c, blasint *LDC)
FLOAT *BETA, FLOAT *c, blasint *LDC, char *TRANS_A,char *TRANS_C)
{
blasint m = *M;
@@ -62,14 +62,31 @@ void NAME(blasint *M, blasint *N, FLOAT *ALPHA, FLOAT *a, blasint *LDA,
FLOAT beta = *BETA;
blasint info;
char transa = (*TRANS_A == 'T') || (*TRANS_A == 't') || (*TRANS_A == 'C') || (*TRANS_A == 'c');
char transc = (*TRANS_C == 'T') || (*TRANS_C == 't') || (*TRANS_C == 'C') || (*TRANS_C == 'c');
PRINT_DEBUG_NAME;
info = 0;
if(transa){
if (lda < MAX(1, n))info = 5;
if (lda < MAX(1, m)) info = 5;
if (ldc < MAX(1, m)) info = 8;
} else{
if (lda < MAX(1, m)) info = 5;
}
if(transc){
if (ldc < MAX(1, n)) info = 8;
}else{
if (ldc < MAX(1, m)) info = 8;
}
if (n < 0) info = 2;
if (m < 0) info = 1;
@@ -80,7 +97,7 @@ void NAME(blasint *M, blasint *N, FLOAT *ALPHA, FLOAT *a, blasint *LDA,
}
#else
void CNAME( enum CBLAS_ORDER order, blasint m, blasint n, FLOAT alpha, FLOAT *a, blasint lda, FLOAT beta,
void CNAME( enum CBLAS_ORDER order,enum CBLAS_TRANSPOSE transa, enum CBLAS_TRANSPOSE transc,blasint m, blasint n, FLOAT alpha, FLOAT *a, blasint lda, FLOAT beta,
FLOAT *c, blasint ldc)
{
/*
@@ -100,9 +117,17 @@ void CNAME(enum CBLAS_ORDER order,
if (order == CblasColMajor) {
info = -1;
if ( (transc == CblasNoTrans) || (transc == CblasConjNoTrans) ) {
if (ldc < MAX(1, m)) info = 8;
} else {
if (ldc < MAX(1, n)) info = 8;
}
if (ldc < MAX(1, m)) info = 8;
if (lda < MAX(1, m)) info = 5;
if ( (transa == CblasNoTrans) || (transa == CblasConjNoTrans) ) {
if (lda < MAX(1, m)) info = 5;
} else {
if (lda < MAX(1, n)) info = 5;
}
if (n < 0) info = 2;
if (m < 0) info = 1;
@@ -115,8 +140,17 @@ void CNAME(enum CBLAS_ORDER order,
n = m;
m = t;
if (ldc < MAX(1, m)) info = 8;
if (lda < MAX(1, m)) info = 5;
if ( (transc == CblasNoTrans) || (transc == CblasConjNoTrans) ) {
if (ldc < MAX(1, m)) info = 8;
} else {
if (ldc < MAX(1, n)) info = 8;
}
if ( (transa == CblasNoTrans) || (transa == CblasConjNoTrans) ) {
if (lda < MAX(1, m)) info = 5;
} else {
if (lda < MAX(1, n)) info = 5;
}
if (n < 0) info = 1;
if (m < 0) info = 2;
}
@@ -136,7 +170,14 @@ void CNAME(enum CBLAS_ORDER order,
FUNCTION_PROFILE_START();
GEADD_K(m,n,alpha, a, lda, beta, c, ldc);
GEADD_K(m,n,alpha, a, lda, beta, c, ldc,
#ifdef CBLAS
(transa == CblasTrans) || (transa == CblasConjTrans),
(transc == CblasTrans) || (transc == CblasConjTrans)
#else
transa, transc
#endif
);
FUNCTION_PROFILE_END(1, 2* m * n , 2 * m * n);
+61 -11
View File
@@ -51,7 +51,7 @@
#ifndef CBLAS
void NAME(blasint *M, blasint *N, FLOAT *ALPHA, FLOAT *a, blasint *LDA,
FLOAT *BETA, FLOAT *c, blasint *LDC)
FLOAT *BETA, FLOAT *c, blasint *LDC,char *TRANS_A,char *TRANS_C)
{
blasint m = *M;
@@ -60,14 +60,34 @@ void NAME(blasint *M, blasint *N, FLOAT *ALPHA, FLOAT *a, blasint *LDA,
blasint ldc = *LDC;
blasint info;
char transa = (*TRANS_A == 'T') || (*TRANS_A == 't') || (*TRANS_A == 'C') || (*TRANS_A == 'c');
char transc = (*TRANS_C == 'T') || (*TRANS_C == 't') || (*TRANS_C == 'C') || (*TRANS_C == 'c');
PRINT_DEBUG_NAME;
info = 0;
if (lda < MAX(1, m)) info = 5;
if (ldc < MAX(1, m)) info = 8;
if(transa){
if (lda < MAX(1, n))info = 5;
} else{
if (lda < MAX(1, m)) info = 5;
}
if(transc){
if (ldc < MAX(1, n)) info = 8;
}else{
if (ldc < MAX(1, m)) info = 8;
}
if (n < 0) info = 2;
if (m < 0) info = 1;
@@ -78,7 +98,7 @@ void NAME(blasint *M, blasint *N, FLOAT *ALPHA, FLOAT *a, blasint *LDA,
}
#else
void CNAME( enum CBLAS_ORDER order, blasint m, blasint n, FLOAT *ALPHA, FLOAT *a, blasint lda, FLOAT *BETA,
void CNAME( enum CBLAS_ORDER order,enum CBLAS_TRANSPOSE transa, enum CBLAS_TRANSPOSE transc, blasint m, blasint n, FLOAT *ALPHA, FLOAT *a, blasint lda, FLOAT *BETA,
FLOAT *c, blasint ldc)
{
/*
@@ -99,11 +119,19 @@ void CNAME(enum CBLAS_ORDER order,
info = -1;
if (ldc < MAX(1, m)) info = 8;
if (lda < MAX(1, m)) info = 5;
if (n < 0) info = 2;
if (m < 0) info = 1;
if ( (transc == CblasNoTrans) || (transc == CblasConjNoTrans) ) {
if (ldc < MAX(1, m)) info = 8;
} else {
if (ldc < MAX(1, n)) info = 8;
}
if ( (transa == CblasNoTrans) || (transa == CblasConjNoTrans) ) {
if (lda < MAX(1, m)) info = 5;
} else {
if (lda < MAX(1, n)) info = 5;
}
if (n < 0) info = 2;
if (m < 0) info = 1;
}
if (order == CblasRowMajor) {
@@ -112,13 +140,24 @@ void CNAME(enum CBLAS_ORDER order,
t = n;
n = m;
m = t;
if ( (transc == CblasNoTrans) || (transc == CblasConjNoTrans) ) {
if (ldc < MAX(1, m)) info = 8;
} else {
if (ldc < MAX(1, n)) info = 8;
}
if (ldc < MAX(1, m)) info = 8;
if (lda < MAX(1, m)) info = 5;
if ( (transa == CblasNoTrans) || (transa == CblasConjNoTrans) ) {
if (lda < MAX(1, m)) info = 5;
} else {
if (lda < MAX(1, n)) info = 5;
}
if (n < 0) info = 1;
if (m < 0) info = 2;
}
if (info >= 0) {
BLASFUNC(xerbla)(ERROR_NAME, &info, sizeof(ERROR_NAME));
return;
@@ -134,7 +173,18 @@ void CNAME(enum CBLAS_ORDER order,
FUNCTION_PROFILE_START();
GEADD_K(m,n,ALPHA[0],ALPHA[1], a, lda, BETA[0], BETA[1], c, ldc);
GEADD_K(m,n,ALPHA[0],ALPHA[1], a, lda, BETA[0], BETA[1], c, ldc,
#ifdef CBLAS
(transa == CblasTrans) || (transa == CblasConjTrans),
(transc == CblasTrans) || (transc == CblasConjTrans)
#else
transa, transc
#endif
);
FUNCTION_PROFILE_END(1, 2* m * n , 2 * m * n);
+7 -5
View File
@@ -262,16 +262,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static RETURN_TYPE dot_kernel_asimd(BLASLONG n, FLOAT *x, BLASLONG inc_x, FLOAT *y, BLASLONG inc_y)
{
#ifndef DOUBLE
volatile
#endif
RETURN_TYPE dot = 0.0;
BLASLONG j = 0;
__asm__ __volatile__ (
" fmov "OUT", "REG0" \n"
" fmov d0, xzr \n"
" fmov d1, xzr \n"
" fmov d2, xzr \n"
" fmov d2, xzr \n"
" fmov d3, xzr \n"
" fmov d4, xzr \n"
" fmov d5, xzr \n"
@@ -342,7 +341,10 @@ static RETURN_TYPE dot_kernel_asimd(BLASLONG n, FLOAT *x, BLASLONG inc_x, FLOAT
[J_] "r" (j)
: "cc",
"memory",
"d1", "d2", "d3", "d4", "d5", "d6", "d7"
"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
"v16", "v17", "v18", "v19", "v20", "v21", "v22",
"v23", "v24", "v25", "v26", "v27", "v28", "v29",
"v30", "v31"
);
return dot;
+57 -32
View File
@@ -17,48 +17,73 @@ 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.
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 "common.h"
int CNAME(BLASLONG rows, BLASLONG cols, FLOAT alpha, FLOAT *a, BLASLONG lda,
FLOAT beta, FLOAT *b, BLASLONG ldb, BLASLONG transa,
BLASLONG transb) {
BLASLONG i;
FLOAT *aptr, *bptr;
int CNAME(BLASLONG rows, BLASLONG cols, FLOAT alpha, FLOAT *a, BLASLONG lda, FLOAT beta, FLOAT *b, BLASLONG ldb)
{
BLASLONG i;
FLOAT *aptr,*bptr;
if (rows <= 0)
return (0);
if (cols <= 0)
return (0);
if ( rows <= 0 ) return(0);
if ( cols <= 0 ) return(0);
aptr = a;
bptr = b;
aptr = a;
bptr = b;
if (alpha == 0.0) {
if (!transb) {
for (i = 0; i < cols; i++) {
if ( alpha == 0.0 )
{
for ( i=0; i<cols ; i++ )
{
SCAL_K(rows, 0,0, beta, bptr, 1, NULL, 0,NULL,0);
bptr+=ldb;
}
SCAL_K(rows, 0, 0, beta, bptr, 1, NULL, 0, NULL, 0);
bptr += ldb;
}
} else {
for (i = 0; i < cols; i++) {
return(0);
}
SCAL_K(rows, 0, 0, beta, bptr, ldb, NULL, 0, NULL, 0);
bptr += 1;
}
}
for (i = 0; i < cols; i++) {
AXPBY_K(rows, alpha, aptr, 1, beta, bptr, 1);
aptr += lda;
bptr += ldb;
}
return (0);
}
if (!transa && !transb) {
for (i = 0; i < cols; i++) {
AXPBY_K(rows, alpha, aptr, 1, beta, bptr, 1);
aptr += lda;
bptr += ldb;
}
} else if (transa && !transb) {
for (i = 0; i < cols; i++) {
return(0);
AXPBY_K(rows, alpha, aptr, lda, beta, bptr, 1);
aptr += 1;
bptr += ldb;
}
} else if (!transa && transb) {
for (i = 0; i < cols; i++) {
AXPBY_K(rows, alpha, aptr, 1, beta, bptr, ldb);
aptr += lda;
bptr += 1;
}
} else if (transa && transb) {
for (i = 0; i < cols; i++) {
AXPBY_K(rows, alpha, aptr, lda, beta, bptr, ldb);
aptr += 1;
bptr += 1;
}
}
return (0);
}
+264
View File
@@ -0,0 +1,264 @@
/***************************************************************************
* Copyright (c) 2026, 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.
* *****************************************************************************/
/*
* Portable C GEMM micro-kernel with a 4x4 register tile (16 accumulators).
*
* This is a wider companion to gemmkernel_2x2.c intended for in-order scalar
* cores whose FP FMA has a multi-cycle latency but 1/cycle throughput (e.g.
* SiFive U74: fmadd.d latency 7, repeat rate 1). A 2x2 tile exposes only 4
* independent accumulator chains, which is fewer than the FMA latency and
* leaves the FP pipe stalled on the accumulator dependency. A 4x4 tile keeps
* 16 independent chains -- comfortably above the latency -- and lowers the
* load:FMA ratio from 1:1 to 1:2, so the single load/store pipe stops being
* the bottleneck. RV64G has 32 FP registers, so 16 accumulators + 4 A + 4 B
* fit without spilling.
*
* Packed-data contract (identical to the 2x2 kernel, verified against the
* generic tcopy_4 / ncopy_4 copy routines): the A operand is packed by
* tcopy_<UNROLL_M> into MR-row micro-panels [A(r0,k)..A(r3,k)] per k, and the
* B operand by ncopy_<UNROLL_N> into NR-col micro-panels [B(k,c0)..B(k,c3)]
* per k. Both dimensions are decomposed as 4 / 2 / 1 sub-blocks at the edges.
*/
#include "common.h"
#include "conversion_macros.h"
#ifdef BGEMM
#define C_TO_F32 TO_F32
#else
#define C_TO_F32
#endif
int CNAME(BLASLONG bm,BLASLONG bn,BLASLONG bk,FLOAT alpha,IFLOAT* ba,IFLOAT* bb,FLOAT* C,BLASLONG ldc
#ifdef TRMMKERNEL
,BLASLONG offset
#endif
)
{
BLASLONG i,j,k;
FLOAT *C0,*C1,*C2,*C3;
IFLOAT *ptrba,*ptrbb;
FLOAT r0c0,r1c0,r2c0,r3c0;
FLOAT r0c1,r1c1,r2c1,r3c1;
FLOAT r0c2,r1c2,r2c2,r3c2;
FLOAT r0c3,r1c3,r2c3,r3c3;
IFLOAT a0,a1,a2,a3,b0,b1,b2,b3;
/* ==================== N panels of 4 ==================== */
for (j=0; j<bn/4; j+=1)
{
C0 = C;
C1 = C0+ldc;
C2 = C1+ldc;
C3 = C2+ldc;
ptrba = ba;
/* ---- 4x4 : 4 rows x 4 cols, 16 accumulators ---- */
for (i=0; i<bm/4; i+=1)
{
ptrbb = bb;
r0c0=r1c0=r2c0=r3c0=0;
r0c1=r1c1=r2c1=r3c1=0;
r0c2=r1c2=r2c2=r3c2=0;
r0c3=r1c3=r2c3=r3c3=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0]; b1=ptrbb[1]; b2=ptrbb[2]; b3=ptrbb[3];
a0=ptrba[0]; a1=ptrba[1]; a2=ptrba[2]; a3=ptrba[3];
r0c0+=TO_F32(a0)*TO_F32(b0); r1c0+=TO_F32(a1)*TO_F32(b0); r2c0+=TO_F32(a2)*TO_F32(b0); r3c0+=TO_F32(a3)*TO_F32(b0);
r0c1+=TO_F32(a0)*TO_F32(b1); r1c1+=TO_F32(a1)*TO_F32(b1); r2c1+=TO_F32(a2)*TO_F32(b1); r3c1+=TO_F32(a3)*TO_F32(b1);
r0c2+=TO_F32(a0)*TO_F32(b2); r1c2+=TO_F32(a1)*TO_F32(b2); r2c2+=TO_F32(a2)*TO_F32(b2); r3c2+=TO_F32(a3)*TO_F32(b2);
r0c3+=TO_F32(a0)*TO_F32(b3); r1c3+=TO_F32(a1)*TO_F32(b3); r2c3+=TO_F32(a2)*TO_F32(b3); r3c3+=TO_F32(a3)*TO_F32(b3);
ptrba+=4; ptrbb+=4;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA); C0[1]=TO_OUTPUT(C_TO_F32(C0[1])+r1c0*ALPHA); C0[2]=TO_OUTPUT(C_TO_F32(C0[2])+r2c0*ALPHA); C0[3]=TO_OUTPUT(C_TO_F32(C0[3])+r3c0*ALPHA);
C1[0]=TO_OUTPUT(C_TO_F32(C1[0])+r0c1*ALPHA); C1[1]=TO_OUTPUT(C_TO_F32(C1[1])+r1c1*ALPHA); C1[2]=TO_OUTPUT(C_TO_F32(C1[2])+r2c1*ALPHA); C1[3]=TO_OUTPUT(C_TO_F32(C1[3])+r3c1*ALPHA);
C2[0]=TO_OUTPUT(C_TO_F32(C2[0])+r0c2*ALPHA); C2[1]=TO_OUTPUT(C_TO_F32(C2[1])+r1c2*ALPHA); C2[2]=TO_OUTPUT(C_TO_F32(C2[2])+r2c2*ALPHA); C2[3]=TO_OUTPUT(C_TO_F32(C2[3])+r3c2*ALPHA);
C3[0]=TO_OUTPUT(C_TO_F32(C3[0])+r0c3*ALPHA); C3[1]=TO_OUTPUT(C_TO_F32(C3[1])+r1c3*ALPHA); C3[2]=TO_OUTPUT(C_TO_F32(C3[2])+r2c3*ALPHA); C3[3]=TO_OUTPUT(C_TO_F32(C3[3])+r3c3*ALPHA);
C0+=4; C1+=4; C2+=4; C3+=4;
}
/* ---- 2x4 : 2 rows x 4 cols ---- */
if (bm & 2)
{
ptrbb = bb;
r0c0=r1c0=0; r0c1=r1c1=0; r0c2=r1c2=0; r0c3=r1c3=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0]; b1=ptrbb[1]; b2=ptrbb[2]; b3=ptrbb[3];
a0=ptrba[0]; a1=ptrba[1];
r0c0+=TO_F32(a0)*TO_F32(b0); r1c0+=TO_F32(a1)*TO_F32(b0);
r0c1+=TO_F32(a0)*TO_F32(b1); r1c1+=TO_F32(a1)*TO_F32(b1);
r0c2+=TO_F32(a0)*TO_F32(b2); r1c2+=TO_F32(a1)*TO_F32(b2);
r0c3+=TO_F32(a0)*TO_F32(b3); r1c3+=TO_F32(a1)*TO_F32(b3);
ptrba+=2; ptrbb+=4;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA); C0[1]=TO_OUTPUT(C_TO_F32(C0[1])+r1c0*ALPHA);
C1[0]=TO_OUTPUT(C_TO_F32(C1[0])+r0c1*ALPHA); C1[1]=TO_OUTPUT(C_TO_F32(C1[1])+r1c1*ALPHA);
C2[0]=TO_OUTPUT(C_TO_F32(C2[0])+r0c2*ALPHA); C2[1]=TO_OUTPUT(C_TO_F32(C2[1])+r1c2*ALPHA);
C3[0]=TO_OUTPUT(C_TO_F32(C3[0])+r0c3*ALPHA); C3[1]=TO_OUTPUT(C_TO_F32(C3[1])+r1c3*ALPHA);
C0+=2; C1+=2; C2+=2; C3+=2;
}
/* ---- 1x4 : 1 row x 4 cols ---- */
if (bm & 1)
{
ptrbb = bb;
r0c0=0; r0c1=0; r0c2=0; r0c3=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0]; b1=ptrbb[1]; b2=ptrbb[2]; b3=ptrbb[3];
a0=ptrba[0];
r0c0+=TO_F32(a0)*TO_F32(b0);
r0c1+=TO_F32(a0)*TO_F32(b1);
r0c2+=TO_F32(a0)*TO_F32(b2);
r0c3+=TO_F32(a0)*TO_F32(b3);
ptrba+=1; ptrbb+=4;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA);
C1[0]=TO_OUTPUT(C_TO_F32(C1[0])+r0c1*ALPHA);
C2[0]=TO_OUTPUT(C_TO_F32(C2[0])+r0c2*ALPHA);
C3[0]=TO_OUTPUT(C_TO_F32(C3[0])+r0c3*ALPHA);
C0+=1; C1+=1; C2+=1; C3+=1;
}
bb = bb + bk*4;
C = C + ldc*4;
}
/* ==================== N panel of 2 ==================== */
if (bn & 2)
{
C0 = C;
C1 = C0+ldc;
ptrba = ba;
for (i=0; i<bm/4; i+=1)
{
ptrbb = bb;
r0c0=r1c0=r2c0=r3c0=0;
r0c1=r1c1=r2c1=r3c1=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0]; b1=ptrbb[1];
a0=ptrba[0]; a1=ptrba[1]; a2=ptrba[2]; a3=ptrba[3];
r0c0+=TO_F32(a0)*TO_F32(b0); r1c0+=TO_F32(a1)*TO_F32(b0); r2c0+=TO_F32(a2)*TO_F32(b0); r3c0+=TO_F32(a3)*TO_F32(b0);
r0c1+=TO_F32(a0)*TO_F32(b1); r1c1+=TO_F32(a1)*TO_F32(b1); r2c1+=TO_F32(a2)*TO_F32(b1); r3c1+=TO_F32(a3)*TO_F32(b1);
ptrba+=4; ptrbb+=2;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA); C0[1]=TO_OUTPUT(C_TO_F32(C0[1])+r1c0*ALPHA); C0[2]=TO_OUTPUT(C_TO_F32(C0[2])+r2c0*ALPHA); C0[3]=TO_OUTPUT(C_TO_F32(C0[3])+r3c0*ALPHA);
C1[0]=TO_OUTPUT(C_TO_F32(C1[0])+r0c1*ALPHA); C1[1]=TO_OUTPUT(C_TO_F32(C1[1])+r1c1*ALPHA); C1[2]=TO_OUTPUT(C_TO_F32(C1[2])+r2c1*ALPHA); C1[3]=TO_OUTPUT(C_TO_F32(C1[3])+r3c1*ALPHA);
C0+=4; C1+=4;
}
if (bm & 2)
{
ptrbb = bb;
r0c0=r1c0=0; r0c1=r1c1=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0]; b1=ptrbb[1];
a0=ptrba[0]; a1=ptrba[1];
r0c0+=TO_F32(a0)*TO_F32(b0); r1c0+=TO_F32(a1)*TO_F32(b0);
r0c1+=TO_F32(a0)*TO_F32(b1); r1c1+=TO_F32(a1)*TO_F32(b1);
ptrba+=2; ptrbb+=2;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA); C0[1]=TO_OUTPUT(C_TO_F32(C0[1])+r1c0*ALPHA);
C1[0]=TO_OUTPUT(C_TO_F32(C1[0])+r0c1*ALPHA); C1[1]=TO_OUTPUT(C_TO_F32(C1[1])+r1c1*ALPHA);
C0+=2; C1+=2;
}
if (bm & 1)
{
ptrbb = bb;
r0c0=0; r0c1=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0]; b1=ptrbb[1];
a0=ptrba[0];
r0c0+=TO_F32(a0)*TO_F32(b0);
r0c1+=TO_F32(a0)*TO_F32(b1);
ptrba+=1; ptrbb+=2;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA);
C1[0]=TO_OUTPUT(C_TO_F32(C1[0])+r0c1*ALPHA);
C0+=1; C1+=1;
}
bb = bb + bk*2;
C = C + ldc*2;
}
/* ==================== N panel of 1 ==================== */
if (bn & 1)
{
C0 = C;
ptrba = ba;
for (i=0; i<bm/4; i+=1)
{
ptrbb = bb;
r0c0=r1c0=r2c0=r3c0=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0];
a0=ptrba[0]; a1=ptrba[1]; a2=ptrba[2]; a3=ptrba[3];
r0c0+=TO_F32(a0)*TO_F32(b0); r1c0+=TO_F32(a1)*TO_F32(b0); r2c0+=TO_F32(a2)*TO_F32(b0); r3c0+=TO_F32(a3)*TO_F32(b0);
ptrba+=4; ptrbb+=1;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA); C0[1]=TO_OUTPUT(C_TO_F32(C0[1])+r1c0*ALPHA); C0[2]=TO_OUTPUT(C_TO_F32(C0[2])+r2c0*ALPHA); C0[3]=TO_OUTPUT(C_TO_F32(C0[3])+r3c0*ALPHA);
C0+=4;
}
if (bm & 2)
{
ptrbb = bb;
r0c0=r1c0=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0];
a0=ptrba[0]; a1=ptrba[1];
r0c0+=TO_F32(a0)*TO_F32(b0); r1c0+=TO_F32(a1)*TO_F32(b0);
ptrba+=2; ptrbb+=1;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA); C0[1]=TO_OUTPUT(C_TO_F32(C0[1])+r1c0*ALPHA);
C0+=2;
}
if (bm & 1)
{
ptrbb = bb;
r0c0=0;
for (k=0; k<bk; k+=1)
{
r0c0+=TO_F32(ptrba[0])*TO_F32(ptrbb[0]);
ptrba+=1; ptrbb+=1;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA);
C0+=1;
}
bb = bb + bk;
C = C + ldc;
}
return 0;
}
+3 -3
View File
@@ -44,9 +44,9 @@ int CNAME(BLASLONG m, BLASLONG n, FLOAT *a, BLASLONG lda, BLASLONG posX, BLASLON
BLASLONG i, js;
BLASLONG X;
FLOAT data01, data02, data03, data04, data05, data06, data07, data08;
FLOAT data09, data10, data11, data12, data13, data14, data15, data16;
FLOAT *ao1, *ao2, *ao3, *ao4;
volatile FLOAT data01, data02, data03, data04, data05, data06, data07, data08;
volatile FLOAT data09, data10, data11, data12, data13, data14, data15, data16;
volatile FLOAT *ao1, *ao2, *ao3, *ao4;
js = (n >> 2);
+3 -3
View File
@@ -44,9 +44,9 @@ int CNAME(BLASLONG m, BLASLONG n, FLOAT *a, BLASLONG lda, BLASLONG posX, BLASLON
BLASLONG i, js;
BLASLONG X;
FLOAT data01, data02, data03, data04, data05, data06, data07, data08;
FLOAT data09, data10, data11, data12, data13, data14, data15, data16;
FLOAT *ao1, *ao2, *ao3, *ao4;
volatile FLOAT data01, data02, data03, data04, data05, data06, data07, data08;
volatile FLOAT data09, data10, data11, data12, data13, data14, data15, data16;
volatile FLOAT *ao1, *ao2, *ao3, *ao4;
js = (n >> 2);
+3 -3
View File
@@ -44,9 +44,9 @@ int CNAME(BLASLONG m, BLASLONG n, FLOAT *a, BLASLONG lda, BLASLONG posX, BLASLON
BLASLONG i, js;
BLASLONG X;
FLOAT data01, data02, data03, data04, data05, data06, data07, data08;
FLOAT data09, data10, data11, data12, data13, data14, data15, data16;
FLOAT *ao1, *ao2, *ao3, *ao4;
volatile FLOAT data01, data02, data03, data04, data05, data06, data07, data08;
volatile FLOAT data09, data10, data11, data12, data13, data14, data15, data16;
volatile FLOAT *ao1, *ao2, *ao3, *ao4;
js = (n >> 2);
+62 -39
View File
@@ -17,49 +17,72 @@ 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.
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 "common.h"
int CNAME(BLASLONG rows, BLASLONG cols, FLOAT alphar, FLOAT alphai, FLOAT *a,
BLASLONG lda, FLOAT betar, FLOAT betai, FLOAT *b, BLASLONG ldb,
BLASLONG transa, BLASLONG transb) {
BLASLONG i;
FLOAT *aptr, *bptr;
BLASLONG lda_elem = lda;
BLASLONG ldb_elem = ldb;
if (rows <= 0)
return (0);
if (cols <= 0)
return (0);
int CNAME(BLASLONG rows, BLASLONG cols, FLOAT alphar, FLOAT alphai, FLOAT *a, BLASLONG lda, FLOAT betar, FLOAT betai , FLOAT *b, BLASLONG ldb)
{
BLASLONG i;
FLOAT *aptr,*bptr;
if ( rows <= 0 ) return(0);
if ( cols <= 0 ) return(0);
aptr = a;
bptr = b;
lda *= 2;
ldb *= 2;
if ( alphar == 0.0 && alphai == 0.0 )
{
for ( i=0; i<cols ; i++ )
{
SCAL_K(rows, 0,0, betar, betai, bptr, 1, NULL, 0,NULL,0);
bptr+=ldb;
}
return(0);
}
for (i = 0; i < cols; i++) {
AXPBY_K(rows, alphar, alphai, aptr, 1, betar, betai, bptr, 1);
aptr += lda;
bptr += ldb;
}
return(0);
aptr = a;
bptr = b;
lda *= 2;
ldb *= 2;
if (alphar == 0.0 && alphai == 0.0) {
if (!transb) {
for (i = 0; i < cols; i++) {
SCAL_K(rows, 0, 0, betar, betai, bptr, 1, NULL, 0, NULL, 0);
bptr += ldb;
}
} else {
for (i = 0; i < cols; i++) {
SCAL_K(rows, 0, 0, betar, betai, bptr, ldb_elem, NULL, 0, NULL, 0);
bptr += 2;
}
}
return (0);
}
if (!transa && !transb) {
for (i = 0; i < cols; i++) {
AXPBY_K(rows, alphar, alphai, aptr, 1, betar, betai, bptr, 1);
aptr += lda;
bptr += ldb;
}
} else if (transa && !transb) {
for (i = 0; i < cols; i++) {
AXPBY_K(rows, alphar, alphai, aptr, lda_elem, betar, betai, bptr, 1);
aptr += 2;
bptr += ldb;
}
} else if (!transa && transb) {
for (i = 0; i < cols; i++) {
AXPBY_K(rows, alphar, alphai, aptr, 1, betar, betai, bptr, ldb_elem);
aptr += lda;
bptr += 2;
}
} else if (transa && transb) {
for (i = 0; i < cols; i++) {
AXPBY_K(rows, alphar, alphai, aptr, lda_elem, betar, betai, bptr,
ldb_elem);
aptr += 2;
bptr += 2;
}
}
return (0);
}
+177
View File
@@ -0,0 +1,177 @@
SAMAXKERNEL = ../riscv64/amax.c
DAMAXKERNEL = ../riscv64/amax.c
CAMAXKERNEL = ../riscv64/zamax.c
ZAMAXKERNEL = ../riscv64/zamax.c
SAMINKERNEL = ../riscv64/amin.c
DAMINKERNEL = ../riscv64/amin.c
CAMINKERNEL = ../riscv64/zamin.c
ZAMINKERNEL = ../riscv64/zamin.c
SMAXKERNEL = ../riscv64/max.c
DMAXKERNEL = ../riscv64/max.c
SMINKERNEL = ../riscv64/min.c
DMINKERNEL = ../riscv64/min.c
ISAMAXKERNEL = ../riscv64/iamax.c
IDAMAXKERNEL = ../riscv64/iamax.c
ICAMAXKERNEL = ../riscv64/izamax.c
IZAMAXKERNEL = ../riscv64/izamax.c
ISAMINKERNEL = ../riscv64/iamin.c
IDAMINKERNEL = ../riscv64/iamin.c
ICAMINKERNEL = ../riscv64/izamin.c
IZAMINKERNEL = ../riscv64/izamin.c
ISMAXKERNEL = ../riscv64/imax.c
IDMAXKERNEL = ../riscv64/imax.c
ISMINKERNEL = ../riscv64/imin.c
IDMINKERNEL = ../riscv64/imin.c
SASUMKERNEL = ../riscv64/asum.c
DASUMKERNEL = ../riscv64/asum.c
CASUMKERNEL = ../riscv64/zasum.c
ZASUMKERNEL = ../riscv64/zasum.c
SSUMKERNEL = ../arm/sum.c
DSUMKERNEL = ../arm/sum.c
CSUMKERNEL = ../arm/zsum.c
ZSUMKERNEL = ../arm/zsum.c
SAXPYKERNEL = ../riscv64/axpy.c
DAXPYKERNEL = ../riscv64/axpy.c
CAXPYKERNEL = ../riscv64/zaxpy.c
ZAXPYKERNEL = ../riscv64/zaxpy.c
SAXPBYKERNEL = ../riscv64/axpby.c
DAXPBYKERNEL = ../riscv64/axpby.c
CAXPBYKERNEL = ../riscv64/zaxpby.c
ZAXPBYKERNEL = ../riscv64/zaxpby.c
SCOPYKERNEL = ../riscv64/copy.c
DCOPYKERNEL = ../riscv64/copy.c
CCOPYKERNEL = ../riscv64/zcopy.c
ZCOPYKERNEL = ../riscv64/zcopy.c
SDOTKERNEL = ../riscv64/dot.c
DDOTKERNEL = ../riscv64/dot.c
CDOTKERNEL = ../riscv64/zdot.c
ZDOTKERNEL = ../riscv64/zdot.c
DSDOTKERNEL = ../generic/dot.c
SNRM2KERNEL = ../riscv64/nrm2.c
DNRM2KERNEL = ../riscv64/nrm2.c
CNRM2KERNEL = ../riscv64/znrm2.c
ZNRM2KERNEL = ../riscv64/znrm2.c
SROTKERNEL = ../riscv64/rot.c
DROTKERNEL = ../riscv64/rot.c
CROTKERNEL = ../riscv64/zrot.c
ZROTKERNEL = ../riscv64/zrot.c
SROTMKERNEL = ../generic/rotm.c
DROTMKERNEL = ../generic/rotm.c
QROTMKERNEL = ../generic/rotm.c
SSCALKERNEL = ../riscv64/scal.c
DSCALKERNEL = ../riscv64/scal.c
CSCALKERNEL = ../riscv64/zscal.c
ZSCALKERNEL = ../riscv64/zscal.c
SSWAPKERNEL = ../riscv64/swap.c
DSWAPKERNEL = ../riscv64/swap.c
CSWAPKERNEL = ../riscv64/zswap.c
ZSWAPKERNEL = ../riscv64/zswap.c
SGEMVNKERNEL = ../riscv64/gemv_n.c
DGEMVNKERNEL = ../riscv64/gemv_n.c
CGEMVNKERNEL = ../riscv64/zgemv_n.c
ZGEMVNKERNEL = ../riscv64/zgemv_n.c
SGEMVTKERNEL = ../riscv64/gemv_t.c
DGEMVTKERNEL = ../riscv64/gemv_t.c
CGEMVTKERNEL = ../riscv64/zgemv_t.c
ZGEMVTKERNEL = ../riscv64/zgemv_t.c
# Real S/D TRMM use the generic 4x4 kernel to match the 4x4 GEMM unroll.
STRMMKERNEL = ../generic/trmmkernel_4x4.c
DTRMMKERNEL = ../generic/trmmkernel_4x4.c
CTRMMKERNEL = ../generic/ztrmmkernel_2x2.c
ZTRMMKERNEL = ../generic/ztrmmkernel_2x2.c
# Real S/D GEMM use the 4x4 register-tiled kernel (16 accumulators) with the
# matching width-4 packing routines. UNROLL_M == UNROLL_N == 4.
SGEMMKERNEL = ../generic/gemmkernel_4x4.c
SGEMMONCOPY = ../generic/gemm_ncopy_4.c
SGEMMOTCOPY = ../generic/gemm_tcopy_4.c
SGEMMONCOPYOBJ = sgemm_oncopy$(TSUFFIX).$(SUFFIX)
SGEMMOTCOPYOBJ = sgemm_otcopy$(TSUFFIX).$(SUFFIX)
DGEMMKERNEL = ../riscv64/gemmkernel_4x4_u74.c
DGEMMONCOPY = ../generic/gemm_ncopy_4.c
DGEMMOTCOPY = ../generic/gemm_tcopy_4.c
DGEMMONCOPYOBJ = dgemm_oncopy$(TSUFFIX).$(SUFFIX)
DGEMMOTCOPYOBJ = dgemm_otcopy$(TSUFFIX).$(SUFFIX)
CGEMMKERNEL = ../generic/zgemmkernel_2x2.c
CGEMMONCOPY = ../generic/zgemm_ncopy_2.c
CGEMMOTCOPY = ../generic/zgemm_tcopy_2.c
CGEMMONCOPYOBJ = cgemm_oncopy$(TSUFFIX).$(SUFFIX)
CGEMMOTCOPYOBJ = cgemm_otcopy$(TSUFFIX).$(SUFFIX)
ZGEMMKERNEL = ../generic/zgemmkernel_2x2.c
ZGEMMONCOPY = ../generic/zgemm_ncopy_2.c
ZGEMMOTCOPY = ../generic/zgemm_tcopy_2.c
ZGEMMONCOPYOBJ = zgemm_oncopy$(TSUFFIX).$(SUFFIX)
ZGEMMOTCOPYOBJ = zgemm_otcopy$(TSUFFIX).$(SUFFIX)
STRSMKERNEL_LN = ../generic/trsm_kernel_LN.c
STRSMKERNEL_LT = ../generic/trsm_kernel_LT.c
STRSMKERNEL_RN = ../generic/trsm_kernel_RN.c
STRSMKERNEL_RT = ../generic/trsm_kernel_RT.c
DTRSMKERNEL_LN = ../generic/trsm_kernel_LN.c
DTRSMKERNEL_LT = ../generic/trsm_kernel_LT.c
DTRSMKERNEL_RN = ../generic/trsm_kernel_RN.c
DTRSMKERNEL_RT = ../generic/trsm_kernel_RT.c
CTRSMKERNEL_LN = ../generic/trsm_kernel_LN.c
CTRSMKERNEL_LT = ../generic/trsm_kernel_LT.c
CTRSMKERNEL_RN = ../generic/trsm_kernel_RN.c
CTRSMKERNEL_RT = ../generic/trsm_kernel_RT.c
ZTRSMKERNEL_LN = ../generic/trsm_kernel_LN.c
ZTRSMKERNEL_LT = ../generic/trsm_kernel_LT.c
ZTRSMKERNEL_RN = ../generic/trsm_kernel_RN.c
ZTRSMKERNEL_RT = ../generic/trsm_kernel_RT.c
SSYMV_U_KERNEL = ../generic/symv_k.c
SSYMV_L_KERNEL = ../generic/symv_k.c
DSYMV_U_KERNEL = ../generic/symv_k.c
DSYMV_L_KERNEL = ../generic/symv_k.c
CSYMV_U_KERNEL = ../generic/zsymv_k.c
CSYMV_L_KERNEL = ../generic/zsymv_k.c
ZSYMV_U_KERNEL = ../generic/zsymv_k.c
ZSYMV_L_KERNEL = ../generic/zsymv_k.c
LSAME_KERNEL = ../generic/lsame.c
SCABS_KERNEL = ../generic/cabs.c
DCABS_KERNEL = ../generic/cabs.c
QCABS_KERNEL = ../generic/cabs.c
ifndef SGEMM_BETA
SGEMM_BETA = ../generic/gemm_beta.c
endif
ifndef DGEMM_BETA
DGEMM_BETA = ../generic/gemm_beta.c
endif
ifndef CGEMM_BETA
CGEMM_BETA = ../generic/zgemm_beta.c
endif
ifndef ZGEMM_BETA
ZGEMM_BETA = ../generic/zgemm_beta.c
endif
+526
View File
@@ -0,0 +1,526 @@
/***************************************************************************
* Copyright (c) 2026, 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.
* *****************************************************************************/
/*
* Portable C GEMM micro-kernel with a 4x4 register tile (16 accumulators).
*
* This is a wider companion to gemmkernel_2x2.c intended for in-order scalar
* cores whose FP FMA has a multi-cycle latency but 1/cycle throughput (e.g.
* SiFive U74: fmadd.d latency 7, repeat rate 1). A 2x2 tile exposes only 4
* independent accumulator chains, which is fewer than the FMA latency and
* leaves the FP pipe stalled on the accumulator dependency. A 4x4 tile keeps
* 16 independent chains -- comfortably above the latency -- and lowers the
* load:FMA ratio from 1:1 to 1:2, so the single load/store pipe stops being
* the bottleneck. RV64G has 32 FP registers, so 16 accumulators + 4 A + 4 B
* fit without spilling.
*
* Packed-data contract (identical to the 2x2 kernel, verified against the
* generic tcopy_4 / ncopy_4 copy routines): the A operand is packed by
* tcopy_<UNROLL_M> into MR-row micro-panels [A(r0,k)..A(r3,k)] per k, and the
* B operand by ncopy_<UNROLL_N> into NR-col micro-panels [B(k,c0)..B(k,c3)]
* per k. Both dimensions are decomposed as 4 / 2 / 1 sub-blocks at the edges.
*/
/*
* U74 hybrid variant. The DGEMM fast path (bm, bn multiples of 4, even bk,
* non-TRMM) is served by a hand-scheduled scalar assembly micro-kernel,
* dgemm_u74_asm, embedded below via a top-level __asm__ (readable source in
* kern_u74.S in this directory): a 4x4 register tile with full operand
* double-buffering (P/Q ping-pong) and load-before-FMA issue ordering that
* reaches the U74 FP-pipe peak (~16.5 cycles per 16 fmadd.d). All other
* shapes, odd bk, and the TRMM builds fall back to the portable C 4x4 code
* below. Measured ~+20% single-core DGEMM over the C kernel; four-core HPL vs
* the tuned C kernel is +4% at N=10000 and +10.7% at N=27456 (5.99 GFLOPS,
* ~50% of the 12 GF peak - the best clean figure). Validated against the full
* BLAS Level-3 suite (DGEMM 17,496 calls, 0 failures) and HPL (residual PASSED).
*/
#include "common.h"
#include "../generic/conversion_macros.h"
#ifdef BGEMM
#define C_TO_F32 TO_F32
#else
#define C_TO_F32
#endif
extern int dgemm_u74_asm(BLASLONG,BLASLONG,BLASLONG,FLOAT,IFLOAT*,IFLOAT*,FLOAT*,BLASLONG);
__asm__(
" .text\n"
" .p2align 4\n"
" .type dgemm_u74_asm,@function\n"
"dgemm_u74_asm:\n"
" addi sp, sp, -112\n"
" fsd fs0, 0(sp)\n"
" fsd fs1, 8(sp)\n"
" fsd fs2, 16(sp)\n"
" fsd fs3, 24(sp)\n"
" fsd fs4, 32(sp)\n"
" fsd fs5, 40(sp)\n"
" fsd fs6, 48(sp)\n"
" fsd fs7, 56(sp)\n"
" fsd fs8, 64(sp)\n"
" fsd fs9, 72(sp)\n"
" fsd fs10, 80(sp)\n"
" fsd fs11, 88(sp)\n"
" fsd fa0, 96(sp)\n"
" slli t0, a6, 3\n"
" srli t1, a0, 2\n"
" srli t2, a1, 2\n"
" beqz t2, .Lk4done\n"
".Lk4j:\n"
" mv a0, a5\n"
" add a1, a0, t0\n"
" add a6, a1, t0\n"
" add a7, a6, t0\n"
" mv t3, a3\n"
" mv t5, t1\n"
".Lk4i:\n"
" mv t4, a4\n"
" fmv.d.x ft0, zero\n"
" fmv.d.x ft1, zero\n"
" fmv.d.x ft2, zero\n"
" fmv.d.x ft3, zero\n"
" fmv.d.x ft4, zero\n"
" fmv.d.x ft5, zero\n"
" fmv.d.x ft6, zero\n"
" fmv.d.x ft7, zero\n"
" fmv.d.x ft8, zero\n"
" fmv.d.x ft9, zero\n"
" fmv.d.x ft10, zero\n"
" fmv.d.x ft11, zero\n"
" fmv.d.x fa2, zero\n"
" fmv.d.x fa3, zero\n"
" fmv.d.x fa4, zero\n"
" fmv.d.x fa5, zero\n"
" fld fa0, 0(t3)\n"
" fld fa1, 8(t3)\n"
" fld fa6, 16(t3)\n"
" fld fa7, 24(t3)\n"
" fld fs0, 0(t4)\n"
" fld fs1, 8(t4)\n"
" fld fs2, 16(t4)\n"
" fld fs3, 24(t4)\n"
" addi t3, t3, 32\n"
" addi t4, t4, 32\n"
" srli t6, a2, 1\n"
" addi t6, t6, -1\n"
" beqz t6, .Lk4epi\n"
" .p2align 4\n"
".Lk4body:\n"
" fld fs4, 0(t3)\n"
" fmadd.d ft0, fa0, fs0, ft0\n"
" fld fs5, 8(t3)\n"
" fmadd.d ft1, fa1, fs0, ft1\n"
" fld fs6, 16(t3)\n"
" fmadd.d ft2, fa6, fs0, ft2\n"
" fld fs7, 24(t3)\n"
" fmadd.d ft3, fa7, fs0, ft3\n"
" fld fs8, 0(t4)\n"
" fmadd.d ft4, fa0, fs1, ft4\n"
" fld fs9, 8(t4)\n"
" fmadd.d ft5, fa1, fs1, ft5\n"
" fld fs10, 16(t4)\n"
" fmadd.d ft6, fa6, fs1, ft6\n"
" fld fs11, 24(t4)\n"
" fmadd.d ft7, fa7, fs1, ft7\n"
" addi t3, t3, 32\n"
" fmadd.d ft8, fa0, fs2, ft8\n"
" addi t4, t4, 32\n"
" fmadd.d ft9, fa1, fs2, ft9\n"
" fmadd.d ft10, fa6, fs2, ft10\n"
" fmadd.d ft11, fa7, fs2, ft11\n"
" fmadd.d fa2, fa0, fs3, fa2\n"
" fmadd.d fa3, fa1, fs3, fa3\n"
" fmadd.d fa4, fa6, fs3, fa4\n"
" fmadd.d fa5, fa7, fs3, fa5\n"
" fld fa0, 0(t3)\n"
" fmadd.d ft0, fs4, fs8, ft0\n"
" fld fa1, 8(t3)\n"
" fmadd.d ft1, fs5, fs8, ft1\n"
" fld fa6, 16(t3)\n"
" fmadd.d ft2, fs6, fs8, ft2\n"
" fld fa7, 24(t3)\n"
" fmadd.d ft3, fs7, fs8, ft3\n"
" fld fs0, 0(t4)\n"
" fmadd.d ft4, fs4, fs9, ft4\n"
" fld fs1, 8(t4)\n"
" fmadd.d ft5, fs5, fs9, ft5\n"
" fld fs2, 16(t4)\n"
" fmadd.d ft6, fs6, fs9, ft6\n"
" fld fs3, 24(t4)\n"
" fmadd.d ft7, fs7, fs9, ft7\n"
" addi t3, t3, 32\n"
" fmadd.d ft8, fs4, fs10, ft8\n"
" addi t4, t4, 32\n"
" fmadd.d ft9, fs5, fs10, ft9\n"
" fmadd.d ft10, fs6, fs10, ft10\n"
" fmadd.d ft11, fs7, fs10, ft11\n"
" fmadd.d fa2, fs4, fs11, fa2\n"
" fmadd.d fa3, fs5, fs11, fa3\n"
" fmadd.d fa4, fs6, fs11, fa4\n"
" fmadd.d fa5, fs7, fs11, fa5\n"
" addi t6, t6, -1\n"
" bnez t6, .Lk4body\n"
".Lk4epi:\n"
" fld fs4, 0(t3)\n"
" fmadd.d ft0, fa0, fs0, ft0\n"
" fld fs5, 8(t3)\n"
" fmadd.d ft1, fa1, fs0, ft1\n"
" fld fs6, 16(t3)\n"
" fmadd.d ft2, fa6, fs0, ft2\n"
" fld fs7, 24(t3)\n"
" fmadd.d ft3, fa7, fs0, ft3\n"
" fld fs8, 0(t4)\n"
" fmadd.d ft4, fa0, fs1, ft4\n"
" fld fs9, 8(t4)\n"
" fmadd.d ft5, fa1, fs1, ft5\n"
" fld fs10, 16(t4)\n"
" fmadd.d ft6, fa6, fs1, ft6\n"
" fld fs11, 24(t4)\n"
" fmadd.d ft7, fa7, fs1, ft7\n"
" addi t3, t3, 32\n"
" fmadd.d ft8, fa0, fs2, ft8\n"
" addi t4, t4, 32\n"
" fmadd.d ft9, fa1, fs2, ft9\n"
" fmadd.d ft10, fa6, fs2, ft10\n"
" fmadd.d ft11, fa7, fs2, ft11\n"
" fmadd.d fa2, fa0, fs3, fa2\n"
" fmadd.d fa3, fa1, fs3, fa3\n"
" fmadd.d fa4, fa6, fs3, fa4\n"
" fmadd.d fa5, fa7, fs3, fa5\n"
" fmadd.d ft0, fs4, fs8, ft0\n"
" fmadd.d ft1, fs5, fs8, ft1\n"
" fmadd.d ft2, fs6, fs8, ft2\n"
" fmadd.d ft3, fs7, fs8, ft3\n"
" fmadd.d ft4, fs4, fs9, ft4\n"
" fmadd.d ft5, fs5, fs9, ft5\n"
" fmadd.d ft6, fs6, fs9, ft6\n"
" fmadd.d ft7, fs7, fs9, ft7\n"
" fmadd.d ft8, fs4, fs10, ft8\n"
" fmadd.d ft9, fs5, fs10, ft9\n"
" fmadd.d ft10, fs6, fs10, ft10\n"
" fmadd.d ft11, fs7, fs10, ft11\n"
" fmadd.d fa2, fs4, fs11, fa2\n"
" fmadd.d fa3, fs5, fs11, fa3\n"
" fmadd.d fa4, fs6, fs11, fa4\n"
" fmadd.d fa5, fs7, fs11, fa5\n"
" fld fs4, 96(sp)\n"
" fld fs0, 0(a0)\n"
" fmadd.d fs0, ft0, fs4, fs0\n"
" fsd fs0, 0(a0)\n"
" fld fs1, 8(a0)\n"
" fmadd.d fs1, ft1, fs4, fs1\n"
" fsd fs1, 8(a0)\n"
" fld fs0, 16(a0)\n"
" fmadd.d fs0, ft2, fs4, fs0\n"
" fsd fs0, 16(a0)\n"
" fld fs1, 24(a0)\n"
" fmadd.d fs1, ft3, fs4, fs1\n"
" fsd fs1, 24(a0)\n"
" fld fs0, 0(a1)\n"
" fmadd.d fs0, ft4, fs4, fs0\n"
" fsd fs0, 0(a1)\n"
" fld fs1, 8(a1)\n"
" fmadd.d fs1, ft5, fs4, fs1\n"
" fsd fs1, 8(a1)\n"
" fld fs0, 16(a1)\n"
" fmadd.d fs0, ft6, fs4, fs0\n"
" fsd fs0, 16(a1)\n"
" fld fs1, 24(a1)\n"
" fmadd.d fs1, ft7, fs4, fs1\n"
" fsd fs1, 24(a1)\n"
" fld fs0, 0(a6)\n"
" fmadd.d fs0, ft8, fs4, fs0\n"
" fsd fs0, 0(a6)\n"
" fld fs1, 8(a6)\n"
" fmadd.d fs1, ft9, fs4, fs1\n"
" fsd fs1, 8(a6)\n"
" fld fs0, 16(a6)\n"
" fmadd.d fs0, ft10, fs4, fs0\n"
" fsd fs0, 16(a6)\n"
" fld fs1, 24(a6)\n"
" fmadd.d fs1, ft11, fs4, fs1\n"
" fsd fs1, 24(a6)\n"
" fld fs0, 0(a7)\n"
" fmadd.d fs0, fa2, fs4, fs0\n"
" fsd fs0, 0(a7)\n"
" fld fs1, 8(a7)\n"
" fmadd.d fs1, fa3, fs4, fs1\n"
" fsd fs1, 8(a7)\n"
" fld fs0, 16(a7)\n"
" fmadd.d fs0, fa4, fs4, fs0\n"
" fsd fs0, 16(a7)\n"
" fld fs1, 24(a7)\n"
" fmadd.d fs1, fa5, fs4, fs1\n"
" fsd fs1, 24(a7)\n"
" addi a0, a0, 32\n"
" addi a1, a1, 32\n"
" addi a6, a6, 32\n"
" addi a7, a7, 32\n"
" addi t5, t5, -1\n"
" bnez t5, .Lk4i\n"
" slli t6, a2, 5\n"
" add a4, a4, t6\n"
" slli t6, t0, 2\n"
" add a5, a5, t6\n"
" addi t2, t2, -1\n"
" bnez t2, .Lk4j\n"
".Lk4done:\n"
" fld fs0, 0(sp)\n"
" fld fs1, 8(sp)\n"
" fld fs2, 16(sp)\n"
" fld fs3, 24(sp)\n"
" fld fs4, 32(sp)\n"
" fld fs5, 40(sp)\n"
" fld fs6, 48(sp)\n"
" fld fs7, 56(sp)\n"
" fld fs8, 64(sp)\n"
" fld fs9, 72(sp)\n"
" fld fs10, 80(sp)\n"
" fld fs11, 88(sp)\n"
" addi sp, sp, 112\n"
" li a0, 0\n"
" ret\n"
" .size dgemm_u74_asm, .-dgemm_u74_asm\n"
);
int CNAME(BLASLONG bm,BLASLONG bn,BLASLONG bk,FLOAT alpha,IFLOAT* ba,IFLOAT* bb,FLOAT* C,BLASLONG ldc
#ifdef TRMMKERNEL
,BLASLONG offset
#endif
)
{
BLASLONG i,j,k;
FLOAT *C0,*C1,*C2,*C3;
IFLOAT *ptrba,*ptrbb;
FLOAT r0c0,r1c0,r2c0,r3c0;
FLOAT r0c1,r1c1,r2c1,r3c1;
FLOAT r0c2,r1c2,r2c2,r3c2;
FLOAT r0c3,r1c3,r2c3,r3c3;
IFLOAT a0,a1,a2,a3,b0,b1,b2,b3;
#if defined(DOUBLE) && !defined(TRMMKERNEL)
if (bm > 0 && bn > 0 && bk > 0 && ((bm & 3) == 0) && ((bn & 3) == 0) && ((bk & 1) == 0))
return dgemm_u74_asm(bm, bn, bk, alpha, ba, bb, C, ldc);
#endif
/* ==================== N panels of 4 ==================== */
for (j=0; j<bn/4; j+=1)
{
C0 = C;
C1 = C0+ldc;
C2 = C1+ldc;
C3 = C2+ldc;
ptrba = ba;
/* ---- 4x4 : 4 rows x 4 cols, 16 accumulators ---- */
for (i=0; i<bm/4; i+=1)
{
ptrbb = bb;
r0c0=r1c0=r2c0=r3c0=0;
r0c1=r1c1=r2c1=r3c1=0;
r0c2=r1c2=r2c2=r3c2=0;
r0c3=r1c3=r2c3=r3c3=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0]; b1=ptrbb[1]; b2=ptrbb[2]; b3=ptrbb[3];
a0=ptrba[0]; a1=ptrba[1]; a2=ptrba[2]; a3=ptrba[3];
r0c0+=TO_F32(a0)*TO_F32(b0); r1c0+=TO_F32(a1)*TO_F32(b0); r2c0+=TO_F32(a2)*TO_F32(b0); r3c0+=TO_F32(a3)*TO_F32(b0);
r0c1+=TO_F32(a0)*TO_F32(b1); r1c1+=TO_F32(a1)*TO_F32(b1); r2c1+=TO_F32(a2)*TO_F32(b1); r3c1+=TO_F32(a3)*TO_F32(b1);
r0c2+=TO_F32(a0)*TO_F32(b2); r1c2+=TO_F32(a1)*TO_F32(b2); r2c2+=TO_F32(a2)*TO_F32(b2); r3c2+=TO_F32(a3)*TO_F32(b2);
r0c3+=TO_F32(a0)*TO_F32(b3); r1c3+=TO_F32(a1)*TO_F32(b3); r2c3+=TO_F32(a2)*TO_F32(b3); r3c3+=TO_F32(a3)*TO_F32(b3);
ptrba+=4; ptrbb+=4;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA); C0[1]=TO_OUTPUT(C_TO_F32(C0[1])+r1c0*ALPHA); C0[2]=TO_OUTPUT(C_TO_F32(C0[2])+r2c0*ALPHA); C0[3]=TO_OUTPUT(C_TO_F32(C0[3])+r3c0*ALPHA);
C1[0]=TO_OUTPUT(C_TO_F32(C1[0])+r0c1*ALPHA); C1[1]=TO_OUTPUT(C_TO_F32(C1[1])+r1c1*ALPHA); C1[2]=TO_OUTPUT(C_TO_F32(C1[2])+r2c1*ALPHA); C1[3]=TO_OUTPUT(C_TO_F32(C1[3])+r3c1*ALPHA);
C2[0]=TO_OUTPUT(C_TO_F32(C2[0])+r0c2*ALPHA); C2[1]=TO_OUTPUT(C_TO_F32(C2[1])+r1c2*ALPHA); C2[2]=TO_OUTPUT(C_TO_F32(C2[2])+r2c2*ALPHA); C2[3]=TO_OUTPUT(C_TO_F32(C2[3])+r3c2*ALPHA);
C3[0]=TO_OUTPUT(C_TO_F32(C3[0])+r0c3*ALPHA); C3[1]=TO_OUTPUT(C_TO_F32(C3[1])+r1c3*ALPHA); C3[2]=TO_OUTPUT(C_TO_F32(C3[2])+r2c3*ALPHA); C3[3]=TO_OUTPUT(C_TO_F32(C3[3])+r3c3*ALPHA);
C0+=4; C1+=4; C2+=4; C3+=4;
}
/* ---- 2x4 : 2 rows x 4 cols ---- */
if (bm & 2)
{
ptrbb = bb;
r0c0=r1c0=0; r0c1=r1c1=0; r0c2=r1c2=0; r0c3=r1c3=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0]; b1=ptrbb[1]; b2=ptrbb[2]; b3=ptrbb[3];
a0=ptrba[0]; a1=ptrba[1];
r0c0+=TO_F32(a0)*TO_F32(b0); r1c0+=TO_F32(a1)*TO_F32(b0);
r0c1+=TO_F32(a0)*TO_F32(b1); r1c1+=TO_F32(a1)*TO_F32(b1);
r0c2+=TO_F32(a0)*TO_F32(b2); r1c2+=TO_F32(a1)*TO_F32(b2);
r0c3+=TO_F32(a0)*TO_F32(b3); r1c3+=TO_F32(a1)*TO_F32(b3);
ptrba+=2; ptrbb+=4;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA); C0[1]=TO_OUTPUT(C_TO_F32(C0[1])+r1c0*ALPHA);
C1[0]=TO_OUTPUT(C_TO_F32(C1[0])+r0c1*ALPHA); C1[1]=TO_OUTPUT(C_TO_F32(C1[1])+r1c1*ALPHA);
C2[0]=TO_OUTPUT(C_TO_F32(C2[0])+r0c2*ALPHA); C2[1]=TO_OUTPUT(C_TO_F32(C2[1])+r1c2*ALPHA);
C3[0]=TO_OUTPUT(C_TO_F32(C3[0])+r0c3*ALPHA); C3[1]=TO_OUTPUT(C_TO_F32(C3[1])+r1c3*ALPHA);
C0+=2; C1+=2; C2+=2; C3+=2;
}
/* ---- 1x4 : 1 row x 4 cols ---- */
if (bm & 1)
{
ptrbb = bb;
r0c0=0; r0c1=0; r0c2=0; r0c3=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0]; b1=ptrbb[1]; b2=ptrbb[2]; b3=ptrbb[3];
a0=ptrba[0];
r0c0+=TO_F32(a0)*TO_F32(b0);
r0c1+=TO_F32(a0)*TO_F32(b1);
r0c2+=TO_F32(a0)*TO_F32(b2);
r0c3+=TO_F32(a0)*TO_F32(b3);
ptrba+=1; ptrbb+=4;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA);
C1[0]=TO_OUTPUT(C_TO_F32(C1[0])+r0c1*ALPHA);
C2[0]=TO_OUTPUT(C_TO_F32(C2[0])+r0c2*ALPHA);
C3[0]=TO_OUTPUT(C_TO_F32(C3[0])+r0c3*ALPHA);
C0+=1; C1+=1; C2+=1; C3+=1;
}
bb = bb + bk*4;
C = C + ldc*4;
}
/* ==================== N panel of 2 ==================== */
if (bn & 2)
{
C0 = C;
C1 = C0+ldc;
ptrba = ba;
for (i=0; i<bm/4; i+=1)
{
ptrbb = bb;
r0c0=r1c0=r2c0=r3c0=0;
r0c1=r1c1=r2c1=r3c1=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0]; b1=ptrbb[1];
a0=ptrba[0]; a1=ptrba[1]; a2=ptrba[2]; a3=ptrba[3];
r0c0+=TO_F32(a0)*TO_F32(b0); r1c0+=TO_F32(a1)*TO_F32(b0); r2c0+=TO_F32(a2)*TO_F32(b0); r3c0+=TO_F32(a3)*TO_F32(b0);
r0c1+=TO_F32(a0)*TO_F32(b1); r1c1+=TO_F32(a1)*TO_F32(b1); r2c1+=TO_F32(a2)*TO_F32(b1); r3c1+=TO_F32(a3)*TO_F32(b1);
ptrba+=4; ptrbb+=2;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA); C0[1]=TO_OUTPUT(C_TO_F32(C0[1])+r1c0*ALPHA); C0[2]=TO_OUTPUT(C_TO_F32(C0[2])+r2c0*ALPHA); C0[3]=TO_OUTPUT(C_TO_F32(C0[3])+r3c0*ALPHA);
C1[0]=TO_OUTPUT(C_TO_F32(C1[0])+r0c1*ALPHA); C1[1]=TO_OUTPUT(C_TO_F32(C1[1])+r1c1*ALPHA); C1[2]=TO_OUTPUT(C_TO_F32(C1[2])+r2c1*ALPHA); C1[3]=TO_OUTPUT(C_TO_F32(C1[3])+r3c1*ALPHA);
C0+=4; C1+=4;
}
if (bm & 2)
{
ptrbb = bb;
r0c0=r1c0=0; r0c1=r1c1=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0]; b1=ptrbb[1];
a0=ptrba[0]; a1=ptrba[1];
r0c0+=TO_F32(a0)*TO_F32(b0); r1c0+=TO_F32(a1)*TO_F32(b0);
r0c1+=TO_F32(a0)*TO_F32(b1); r1c1+=TO_F32(a1)*TO_F32(b1);
ptrba+=2; ptrbb+=2;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA); C0[1]=TO_OUTPUT(C_TO_F32(C0[1])+r1c0*ALPHA);
C1[0]=TO_OUTPUT(C_TO_F32(C1[0])+r0c1*ALPHA); C1[1]=TO_OUTPUT(C_TO_F32(C1[1])+r1c1*ALPHA);
C0+=2; C1+=2;
}
if (bm & 1)
{
ptrbb = bb;
r0c0=0; r0c1=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0]; b1=ptrbb[1];
a0=ptrba[0];
r0c0+=TO_F32(a0)*TO_F32(b0);
r0c1+=TO_F32(a0)*TO_F32(b1);
ptrba+=1; ptrbb+=2;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA);
C1[0]=TO_OUTPUT(C_TO_F32(C1[0])+r0c1*ALPHA);
C0+=1; C1+=1;
}
bb = bb + bk*2;
C = C + ldc*2;
}
/* ==================== N panel of 1 ==================== */
if (bn & 1)
{
C0 = C;
ptrba = ba;
for (i=0; i<bm/4; i+=1)
{
ptrbb = bb;
r0c0=r1c0=r2c0=r3c0=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0];
a0=ptrba[0]; a1=ptrba[1]; a2=ptrba[2]; a3=ptrba[3];
r0c0+=TO_F32(a0)*TO_F32(b0); r1c0+=TO_F32(a1)*TO_F32(b0); r2c0+=TO_F32(a2)*TO_F32(b0); r3c0+=TO_F32(a3)*TO_F32(b0);
ptrba+=4; ptrbb+=1;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA); C0[1]=TO_OUTPUT(C_TO_F32(C0[1])+r1c0*ALPHA); C0[2]=TO_OUTPUT(C_TO_F32(C0[2])+r2c0*ALPHA); C0[3]=TO_OUTPUT(C_TO_F32(C0[3])+r3c0*ALPHA);
C0+=4;
}
if (bm & 2)
{
ptrbb = bb;
r0c0=r1c0=0;
for (k=0; k<bk; k+=1)
{
b0=ptrbb[0];
a0=ptrba[0]; a1=ptrba[1];
r0c0+=TO_F32(a0)*TO_F32(b0); r1c0+=TO_F32(a1)*TO_F32(b0);
ptrba+=2; ptrbb+=1;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA); C0[1]=TO_OUTPUT(C_TO_F32(C0[1])+r1c0*ALPHA);
C0+=2;
}
if (bm & 1)
{
ptrbb = bb;
r0c0=0;
for (k=0; k<bk; k+=1)
{
r0c0+=TO_F32(ptrba[0])*TO_F32(ptrbb[0]);
ptrba+=1; ptrbb+=1;
}
C0[0]=TO_OUTPUT(C_TO_F32(C0[0])+r0c0*ALPHA);
C0+=1;
}
bb = bb + bk;
C = C + ldc;
}
return 0;
}
+267
View File
@@ -0,0 +1,267 @@
/*
* dgemm 4x4 scalar micro-kernel for SiFive U74 (RV64GC, lp64d). v3:
* software-pipelined, full operand double-buffering (P/Q ping-pong), one-
* iteration lookahead, LOAD-BEFORE-FMA issue ordering (the U74 dual-issue
* pairs a load/int in slot0 with an FP op in slot1, so each fld is emitted
* immediately before the fmadd it co-issues with). 16 FP accumulators + 16 FP
* operand regs = all 32 FP regs; alpha spilled for the k-loop. Handles the
* bm%4==0 && bn%4==0 grid with EVEN bk (bk>=2); ragged edges + odd bk later.
*
* int kern_asm(long bm,long bn,long bk,double alpha,double* A,double* B,double* C,long ldc)
* a0=bm a1=bn a2=bk fa0=alpha a3=A a4=B a5=C a6=ldc
* acc: col0 ft0..ft3 col1 ft4..ft7 col2 ft8..ft11 col3 fa2..fa5
* P: A=fa0,fa1,fa6,fa7 B=fs0,fs1,fs2,fs3 Q: A=fs4,fs5,fs6,fs7 B=fs8,fs9,fs10,fs11
* int: t0=ldc*8 t1=bm/4 t2=j t3=ptrA t4=ptrB t5=i t6=pair-cnt C0..3=a0,a1,a6,a7
*/
.text
.p2align 4
.globl kern_asm
.type kern_asm,@function
kern_asm:
addi sp, sp, -112
fsd fs0, 0(sp)
fsd fs1, 8(sp)
fsd fs2, 16(sp)
fsd fs3, 24(sp)
fsd fs4, 32(sp)
fsd fs5, 40(sp)
fsd fs6, 48(sp)
fsd fs7, 56(sp)
fsd fs8, 64(sp)
fsd fs9, 72(sp)
fsd fs10, 80(sp)
fsd fs11, 88(sp)
fsd fa0, 96(sp) # spill alpha
slli t0, a6, 3 # ldc*8
srli t1, a0, 2 # bm/4
srli t2, a1, 2 # bn/4 (j)
beqz t2, .Ldone
.Lj:
mv a0, a5 # C0 = Crun
add a1, a0, t0 # C1
add a6, a1, t0 # C2
add a7, a6, t0 # C3
mv t3, a3 # ptrA = ba
mv t5, t1 # i = bm/4
.Li:
mv t4, a4 # ptrB = bb(run)
fmv.d.x ft0, zero
fmv.d.x ft1, zero
fmv.d.x ft2, zero
fmv.d.x ft3, zero
fmv.d.x ft4, zero
fmv.d.x ft5, zero
fmv.d.x ft6, zero
fmv.d.x ft7, zero
fmv.d.x ft8, zero
fmv.d.x ft9, zero
fmv.d.x ft10, zero
fmv.d.x ft11, zero
fmv.d.x fa2, zero
fmv.d.x fa3, zero
fmv.d.x fa4, zero
fmv.d.x fa5, zero
# preload P from k=0, advance to k=1
fld fa0, 0(t3)
fld fa1, 8(t3)
fld fa6, 16(t3)
fld fa7, 24(t3)
fld fs0, 0(t4)
fld fs1, 8(t4)
fld fs2, 16(t4)
fld fs3, 24(t4)
addi t3, t3, 32
addi t4, t4, 32
srli t6, a2, 1 # bk/2
addi t6, t6, -1 # pair-cnt = bk/2 - 1
beqz t6, .Lepi
.p2align 4
.Lbody: # --- P current, load Q (load before paired fmadd) ---
fld fs4, 0(t3)
fmadd.d ft0, fa0, fs0, ft0
fld fs5, 8(t3)
fmadd.d ft1, fa1, fs0, ft1
fld fs6, 16(t3)
fmadd.d ft2, fa6, fs0, ft2
fld fs7, 24(t3)
fmadd.d ft3, fa7, fs0, ft3
fld fs8, 0(t4)
fmadd.d ft4, fa0, fs1, ft4
fld fs9, 8(t4)
fmadd.d ft5, fa1, fs1, ft5
fld fs10, 16(t4)
fmadd.d ft6, fa6, fs1, ft6
fld fs11, 24(t4)
fmadd.d ft7, fa7, fs1, ft7
addi t3, t3, 32
fmadd.d ft8, fa0, fs2, ft8
addi t4, t4, 32
fmadd.d ft9, fa1, fs2, ft9
fmadd.d ft10, fa6, fs2, ft10
fmadd.d ft11, fa7, fs2, ft11
fmadd.d fa2, fa0, fs3, fa2
fmadd.d fa3, fa1, fs3, fa3
fmadd.d fa4, fa6, fs3, fa4
fmadd.d fa5, fa7, fs3, fa5
# --- Q current, load P ---
fld fa0, 0(t3)
fmadd.d ft0, fs4, fs8, ft0
fld fa1, 8(t3)
fmadd.d ft1, fs5, fs8, ft1
fld fa6, 16(t3)
fmadd.d ft2, fs6, fs8, ft2
fld fa7, 24(t3)
fmadd.d ft3, fs7, fs8, ft3
fld fs0, 0(t4)
fmadd.d ft4, fs4, fs9, ft4
fld fs1, 8(t4)
fmadd.d ft5, fs5, fs9, ft5
fld fs2, 16(t4)
fmadd.d ft6, fs6, fs9, ft6
fld fs3, 24(t4)
fmadd.d ft7, fs7, fs9, ft7
addi t3, t3, 32
fmadd.d ft8, fs4, fs10, ft8
addi t4, t4, 32
fmadd.d ft9, fs5, fs10, ft9
fmadd.d ft10, fs6, fs10, ft10
fmadd.d ft11, fs7, fs10, ft11
fmadd.d fa2, fs4, fs11, fa2
fmadd.d fa3, fs5, fs11, fa3
fmadd.d fa4, fs6, fs11, fa4
fmadd.d fa5, fs7, fs11, fa5
addi t6, t6, -1
bnez t6, .Lbody
.Lepi: # --- P current, load last Q ---
fld fs4, 0(t3)
fmadd.d ft0, fa0, fs0, ft0
fld fs5, 8(t3)
fmadd.d ft1, fa1, fs0, ft1
fld fs6, 16(t3)
fmadd.d ft2, fa6, fs0, ft2
fld fs7, 24(t3)
fmadd.d ft3, fa7, fs0, ft3
fld fs8, 0(t4)
fmadd.d ft4, fa0, fs1, ft4
fld fs9, 8(t4)
fmadd.d ft5, fa1, fs1, ft5
fld fs10, 16(t4)
fmadd.d ft6, fa6, fs1, ft6
fld fs11, 24(t4)
fmadd.d ft7, fa7, fs1, ft7
addi t3, t3, 32
fmadd.d ft8, fa0, fs2, ft8
addi t4, t4, 32
fmadd.d ft9, fa1, fs2, ft9
fmadd.d ft10, fa6, fs2, ft10
fmadd.d ft11, fa7, fs2, ft11
fmadd.d fa2, fa0, fs3, fa2
fmadd.d fa3, fa1, fs3, fa3
fmadd.d fa4, fa6, fs3, fa4
fmadd.d fa5, fa7, fs3, fa5
# --- Q current, compute only ---
fmadd.d ft0, fs4, fs8, ft0
fmadd.d ft1, fs5, fs8, ft1
fmadd.d ft2, fs6, fs8, ft2
fmadd.d ft3, fs7, fs8, ft3
fmadd.d ft4, fs4, fs9, ft4
fmadd.d ft5, fs5, fs9, ft5
fmadd.d ft6, fs6, fs9, ft6
fmadd.d ft7, fs7, fs9, ft7
fmadd.d ft8, fs4, fs10, ft8
fmadd.d ft9, fs5, fs10, ft9
fmadd.d ft10, fs6, fs10, ft10
fmadd.d ft11, fs7, fs10, ft11
fmadd.d fa2, fs4, fs11, fa2
fmadd.d fa3, fs5, fs11, fa3
fmadd.d fa4, fs6, fs11, fa4
fmadd.d fa5, fs7, fs11, fa5
# ---- C += acc*alpha ; alpha->fs4, temps fs0/fs1 ----
fld fs4, 96(sp)
fld fs0, 0(a0)
fmadd.d fs0, ft0, fs4, fs0
fsd fs0, 0(a0)
fld fs1, 8(a0)
fmadd.d fs1, ft1, fs4, fs1
fsd fs1, 8(a0)
fld fs0, 16(a0)
fmadd.d fs0, ft2, fs4, fs0
fsd fs0, 16(a0)
fld fs1, 24(a0)
fmadd.d fs1, ft3, fs4, fs1
fsd fs1, 24(a0)
fld fs0, 0(a1)
fmadd.d fs0, ft4, fs4, fs0
fsd fs0, 0(a1)
fld fs1, 8(a1)
fmadd.d fs1, ft5, fs4, fs1
fsd fs1, 8(a1)
fld fs0, 16(a1)
fmadd.d fs0, ft6, fs4, fs0
fsd fs0, 16(a1)
fld fs1, 24(a1)
fmadd.d fs1, ft7, fs4, fs1
fsd fs1, 24(a1)
fld fs0, 0(a6)
fmadd.d fs0, ft8, fs4, fs0
fsd fs0, 0(a6)
fld fs1, 8(a6)
fmadd.d fs1, ft9, fs4, fs1
fsd fs1, 8(a6)
fld fs0, 16(a6)
fmadd.d fs0, ft10, fs4, fs0
fsd fs0, 16(a6)
fld fs1, 24(a6)
fmadd.d fs1, ft11, fs4, fs1
fsd fs1, 24(a6)
fld fs0, 0(a7)
fmadd.d fs0, fa2, fs4, fs0
fsd fs0, 0(a7)
fld fs1, 8(a7)
fmadd.d fs1, fa3, fs4, fs1
fsd fs1, 8(a7)
fld fs0, 16(a7)
fmadd.d fs0, fa4, fs4, fs0
fsd fs0, 16(a7)
fld fs1, 24(a7)
fmadd.d fs1, fa5, fs4, fs1
fsd fs1, 24(a7)
addi a0, a0, 32
addi a1, a1, 32
addi a6, a6, 32
addi a7, a7, 32
addi t5, t5, -1
bnez t5, .Li
slli t6, a2, 5 # bb(run) += bk*4
add a4, a4, t6
slli t6, t0, 2 # C(run) += 4*ldc
add a5, a5, t6
addi t2, t2, -1
bnez t2, .Lj
.Ldone:
fld fs0, 0(sp)
fld fs1, 8(sp)
fld fs2, 16(sp)
fld fs3, 24(sp)
fld fs4, 32(sp)
fld fs5, 40(sp)
fld fs6, 48(sp)
fld fs7, 56(sp)
fld fs8, 64(sp)
fld fs9, 72(sp)
fld fs10, 80(sp)
fld fs11, 88(sp)
addi sp, sp, 112
li a0, 0
ret
.size kern_asm, .-kern_asm
+3 -4
View File
@@ -351,9 +351,9 @@
* .. Parameters ..
INTEGER MAXITR
PARAMETER ( MAXITR = 6 )
REAL HUNDRED, MEIGHTH, ONE, TEN, ZERO
REAL HUNDRED, MEIGHTH, ZERO, ONE, TEN
PARAMETER ( HUNDRED = 100.0E0, MEIGHTH = -0.125E0,
$ ONE = 1.0E0, TEN = 10.0E0, ZERO = 0.0E0 )
$ ZERO = 0.0E0, ONE = 1.0E0, TEN = 10.0E0 )
COMPLEX NEGONECOMPLEX
PARAMETER ( NEGONECOMPLEX = (-1.0E0,0.0E0) )
REAL PIOVER2
@@ -576,7 +576,7 @@
END IF
ELSE
NU = SIGMA21
MU = SQRT( 1.0 - NU**2 )
MU = SQRT( ONE - NU**2 )
IF( NU .LT. THRESH ) THEN
MU = ONE
NU = ZERO
@@ -1114,4 +1114,3 @@
* End of CBBCSD
*
END
+25 -18
View File
@@ -5,7 +5,6 @@
* Online html documentation available at
* http://www.netlib.org/lapack/explore-html/
*
*> \htmlonly
*> Download CGELSY + dependencies
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cgelsy.f">
*> [TGZ]</a>
@@ -13,7 +12,6 @@
*> [ZIP]</a>
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cgelsy.f">
*> [TXT]</a>
*> \endhtmlonly
*
* Definition:
* ===========
@@ -197,7 +195,7 @@
*> \author Univ. of Colorado Denver
*> \author NAG Ltd.
*
*> \ingroup complexGEsolve
*> \ingroup gelsy
*
*> \par Contributors:
* ==================
@@ -207,8 +205,10 @@
*> G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain \n
*>
* =====================================================================
SUBROUTINE CGELSY( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
SUBROUTINE CGELSY( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND,
$ RANK,
$ WORK, LWORK, RWORK, INFO )
IMPLICIT NONE
*
* -- LAPACK driver routine --
* -- LAPACK is a software package provided by Univ. of Tennessee, --
@@ -244,8 +244,9 @@
COMPLEX C1, C2, S1, S2
* ..
* .. External Subroutines ..
EXTERNAL CCOPY, CGEQP3, CLAIC1, CLASCL, CLASET, CTRSM,
$ CTZRZF, CUNMQR, CUNMRZ, SLABAD, XERBLA
EXTERNAL CCOPY, CGEQP3, CLAIC1, CLASCL, CLASET,
$ CTRSM,
$ CTZRZF, CUNMQR, CUNMRZ, XERBLA
* ..
* .. External Functions ..
INTEGER ILAENV
@@ -265,9 +266,9 @@
*
INFO = 0
NB1 = ILAENV( 1, 'CGEQRF', ' ', M, N, -1, -1 )
NB2 = ILAENV( 1, 'CGERQF', ' ', M, N, -1, -1 )
NB2 = ILAENV( 1, 'CTZRZF', ' ', M, N, -1, -1 )
NB3 = ILAENV( 1, 'CUNMQR', ' ', M, N, NRHS, -1 )
NB4 = ILAENV( 1, 'CUNMRQ', ' ', M, N, NRHS, -1 )
NB4 = ILAENV( 1, 'CUNMRZ', ' ', M, N, NRHS, -1 )
NB = MAX( NB1, NB2, NB3, NB4 )
LWKOPT = MAX( 1, MN+2*N+NB*(N+1), 2*MN+NB*NRHS )
WORK( 1 ) = CMPLX( LWKOPT )
@@ -305,7 +306,6 @@
*
SMLNUM = SLAMCH( 'S' ) / SLAMCH( 'P' )
BIGNUM = ONE / SMLNUM
CALL SLABAD( SMLNUM, BIGNUM )
*
* Scale A, B if max entries outside range [SMLNUM,BIGNUM]
*
@@ -338,13 +338,15 @@
*
* Scale matrix norm up to SMLNUM
*
CALL CLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
CALL CLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB,
$ INFO )
IBSCL = 1
ELSE IF( BNRM.GT.BIGNUM ) THEN
*
* Scale matrix norm down to BIGNUM
*
CALL CLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
CALL CLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB,
$ INFO )
IBSCL = 2
END IF
*
@@ -353,7 +355,7 @@
*
CALL CGEQP3( M, N, A, LDA, JPVT, WORK( 1 ), WORK( MN+1 ),
$ LWORK-MN, RWORK, INFO )
WSIZE = MN + REAL( WORK( MN+1 ) )
WSIZE = REAL( MN ) + REAL( WORK( MN+1 ) )
*
* complex workspace: MN+NB*(N+1). real workspace 2*N.
* Details of Householder rotations stored in WORK(1:MN).
@@ -411,9 +413,10 @@
*
* B(1:M,1:NRHS) := Q**H * B(1:M,1:NRHS)
*
CALL CUNMQR( 'Left', 'Conjugate transpose', M, NRHS, MN, A, LDA,
CALL CUNMQR( 'Left', 'Conjugate transpose', M, NRHS, MN, A,
$ LDA,
$ WORK( 1 ), B, LDB, WORK( 2*MN+1 ), LWORK-2*MN, INFO )
WSIZE = MAX( WSIZE, 2*MN+REAL( WORK( 2*MN+1 ) ) )
WSIZE = MAX( WSIZE, REAL( 2*MN )+REAL( WORK( 2*MN+1 ) ) )
*
* complex workspace: 2*MN+NB*NRHS.
*
@@ -452,18 +455,22 @@
* Undo scaling
*
IF( IASCL.EQ.1 ) THEN
CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB,
$ INFO )
CALL CLASCL( 'U', 0, 0, SMLNUM, ANRM, RANK, RANK, A, LDA,
$ INFO )
ELSE IF( IASCL.EQ.2 ) THEN
CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB,
$ INFO )
CALL CLASCL( 'U', 0, 0, BIGNUM, ANRM, RANK, RANK, A, LDA,
$ INFO )
END IF
IF( IBSCL.EQ.1 ) THEN
CALL CLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
CALL CLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB,
$ INFO )
ELSE IF( IBSCL.EQ.2 ) THEN
CALL CLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
CALL CLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB,
$ INFO )
END IF
*
70 CONTINUE
+4 -4
View File
@@ -203,7 +203,7 @@ subroutine CLARTG( f, g, c, s, r )
rtmax = rtmax * 2
if( f2 > rtmin .and. h2 < rtmax ) then
! safmin <= sqrt( f2*h2 ) <= safmax
s = conjg( g ) * ( f / sqrt( f2*h2 ) )
s = ( f / sqrt( f2 ) ) * ( conjg( g ) / sqrt( h2 ) )
else
s = conjg( g ) * ( r / h2 )
end if
@@ -223,7 +223,7 @@ subroutine CLARTG( f, g, c, s, r )
! sqrt(safmin) <= f2 * sqrt(safmax) <= h2 / sqrt(f2 * h2) <= h2 * (safmin / f2) <= h2 <= safmax
r = f * ( h2 / d )
end if
s = conjg( g ) * ( f / d )
s = ( f / sqrt( f2 ) ) * ( conjg( g ) / sqrt( h2 ) )
end if
else
!
@@ -259,7 +259,7 @@ subroutine CLARTG( f, g, c, s, r )
rtmax = rtmax * 2
if( f2 > rtmin .and. h2 < rtmax ) then
! safmin <= sqrt( f2*h2 ) <= safmax
s = conjg( gs ) * ( fs / sqrt( f2*h2 ) )
s = ( fs / sqrt( f2 ) ) * ( conjg( gs ) / sqrt( h2 ) )
else
s = conjg( gs ) * ( r / h2 )
end if
@@ -279,7 +279,7 @@ subroutine CLARTG( f, g, c, s, r )
! sqrt(safmin) <= f2 * sqrt(safmax) <= h2 / sqrt(f2 * h2) <= h2 * (safmin / f2) <= h2 <= safmax
r = fs * ( h2 / d )
end if
s = conjg( gs ) * ( fs / d )
s = ( fs / sqrt( f2 ) ) * ( conjg( gs ) / sqrt( h2 ) )
end if
! Rescale c and r
c = c * w
+5 -3
View File
@@ -414,17 +414,19 @@
* ..
* .. External Functions ..
LOGICAL LSAME
EXTERNAL LSAME
REAL SLAMCH
EXTERNAL LSAME, SLAMCH
* ..
* .. External Subroutines ..
EXTERNAL CCOPY, CLAGS2, CLAPLL, CLASET, CROT, CSSCAL,
$ SLARTG, XERBLA
* ..
* .. Intrinsic Functions ..
INTRINSIC ABS, CONJG, MAX, MIN, REAL, HUGE
PARAMETER ( HUGENUM = HUGE(ZERO) )
INTRINSIC ABS, CONJG, MAX, MIN, REAL
* ..
* .. Executable Statements ..
*
HUGENUM = SLAMCH( 'O' )
*
* Decode and test the input parameters
*
+3 -4
View File
@@ -351,9 +351,9 @@
* .. Parameters ..
INTEGER MAXITR
PARAMETER ( MAXITR = 6 )
DOUBLE PRECISION HUNDRED, MEIGHTH, ONE, TEN, ZERO
DOUBLE PRECISION HUNDRED, MEIGHTH, ZERO, ONE, TEN
PARAMETER ( HUNDRED = 100.0D0, MEIGHTH = -0.125D0,
$ ONE = 1.0D0, TEN = 10.0D0, ZERO = 0.0D0 )
$ ZERO = 0.0D0, ONE = 1.0D0, TEN = 10.0D0 )
DOUBLE PRECISION NEGONE
PARAMETER ( NEGONE = -1.0D0 )
DOUBLE PRECISION PIOVER2
@@ -576,7 +576,7 @@
END IF
ELSE
NU = SIGMA21
MU = SQRT( 1.0 - NU**2 )
MU = SQRT( ONE - NU**2 )
IF( NU .LT. THRESH ) THEN
MU = ONE
NU = ZERO
@@ -1108,4 +1108,3 @@
* End of DBBCSD
*
END
+22 -15
View File
@@ -5,7 +5,6 @@
* Online html documentation available at
* http://www.netlib.org/lapack/explore-html/
*
*> \htmlonly
*> Download DGELSY + dependencies
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgelsy.f">
*> [TGZ]</a>
@@ -13,7 +12,6 @@
*> [ZIP]</a>
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgelsy.f">
*> [TXT]</a>
*> \endhtmlonly
*
* Definition:
* ===========
@@ -191,7 +189,7 @@
*> \author Univ. of Colorado Denver
*> \author NAG Ltd.
*
*> \ingroup doubleGEsolve
*> \ingroup gelsy
*
*> \par Contributors:
* ==================
@@ -201,8 +199,10 @@
*> G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain \n
*>
* =====================================================================
SUBROUTINE DGELSY( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
SUBROUTINE DGELSY( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND,
$ RANK,
$ WORK, LWORK, INFO )
IMPLICIT NONE
*
* -- LAPACK driver routine --
* -- LAPACK is a software package provided by Univ. of Tennessee, --
@@ -238,7 +238,8 @@
EXTERNAL ILAENV, DLAMCH, DLANGE
* ..
* .. External Subroutines ..
EXTERNAL DCOPY, DGEQP3, DLABAD, DLAIC1, DLASCL, DLASET,
EXTERNAL DCOPY, DGEQP3, DLAIC1, DLASCL,
$ DLASET,
$ DORMQR, DORMRZ, DTRSM, DTZRZF, XERBLA
* ..
* .. Intrinsic Functions ..
@@ -274,9 +275,9 @@
LWKOPT = 1
ELSE
NB1 = ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
NB2 = ILAENV( 1, 'DGERQF', ' ', M, N, -1, -1 )
NB2 = ILAENV( 1, 'DTZRZF', ' ', M, N, -1, -1 )
NB3 = ILAENV( 1, 'DORMQR', ' ', M, N, NRHS, -1 )
NB4 = ILAENV( 1, 'DORMRQ', ' ', M, N, NRHS, -1 )
NB4 = ILAENV( 1, 'DORMRZ', ' ', M, N, NRHS, -1 )
NB = MAX( NB1, NB2, NB3, NB4 )
LWKMIN = MN + MAX( 2*MN, N + 1, MN + NRHS )
LWKOPT = MAX( LWKMIN,
@@ -307,7 +308,6 @@
*
SMLNUM = DLAMCH( 'S' ) / DLAMCH( 'P' )
BIGNUM = ONE / SMLNUM
CALL DLABAD( SMLNUM, BIGNUM )
*
* Scale A, B if max entries outside range [SMLNUM,BIGNUM]
*
@@ -340,13 +340,15 @@
*
* Scale matrix norm up to SMLNUM
*
CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
CALL DLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB,
$ INFO )
IBSCL = 1
ELSE IF( BNRM.GT.BIGNUM ) THEN
*
* Scale matrix norm down to BIGNUM
*
CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
CALL DLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB,
$ INFO )
IBSCL = 2
END IF
*
@@ -413,7 +415,8 @@
*
* B(1:M,1:NRHS) := Q**T * B(1:M,1:NRHS)
*
CALL DORMQR( 'Left', 'Transpose', M, NRHS, MN, A, LDA, WORK( 1 ),
CALL DORMQR( 'Left', 'Transpose', M, NRHS, MN, A, LDA,
$ WORK( 1 ),
$ B, LDB, WORK( 2*MN+1 ), LWORK-2*MN, INFO )
WSIZE = MAX( WSIZE, 2*MN+WORK( 2*MN+1 ) )
*
@@ -454,18 +457,22 @@
* Undo scaling
*
IF( IASCL.EQ.1 ) THEN
CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB,
$ INFO )
CALL DLASCL( 'U', 0, 0, SMLNUM, ANRM, RANK, RANK, A, LDA,
$ INFO )
ELSE IF( IASCL.EQ.2 ) THEN
CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB,
$ INFO )
CALL DLASCL( 'U', 0, 0, BIGNUM, ANRM, RANK, RANK, A, LDA,
$ INFO )
END IF
IF( IBSCL.EQ.1 ) THEN
CALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
CALL DLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB,
$ INFO )
ELSE IF( IBSCL.EQ.2 ) THEN
CALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
CALL DLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB,
$ INFO )
END IF
*
70 CONTINUE
+4 -4
View File
@@ -426,10 +426,10 @@
* the statistically correct thing to do in this situation is
* simply to iterate again.
* N.B. the case X( I ) = 0.0 should not be possible.
I1 = I1 + 2
I2 = I2 + 2
I3 = I3 + 2
I4 = I4 + 2
I1 = IT1
I2 = IT2
I3 = IT3
I4 = IT4
GOTO 20
END IF
*
+5 -3
View File
@@ -409,17 +409,19 @@
* ..
* .. External Functions ..
LOGICAL LSAME
EXTERNAL LSAME
DOUBLE PRECISION DLAMCH
EXTERNAL LSAME, DLAMCH
* ..
* .. External Subroutines ..
EXTERNAL DCOPY, DLAGS2, DLAPLL, DLARTG, DLASET, DROT,
$ DSCAL, XERBLA
* ..
* .. Intrinsic Functions ..
INTRINSIC ABS, MAX, MIN, HUGE
PARAMETER ( HUGENUM = HUGE(ZERO) )
INTRINSIC ABS, MAX, MIN
* ..
* .. Executable Statements ..
*
HUGENUM = DLAMCH( 'O' )
*
* Decode and test the input parameters
*
+10
View File
@@ -276,6 +276,16 @@
ELSE
NB = 32
END IF
ELSE IF( SUBNAM(2:6).EQ.'TZRZF' ) THEN
IF( SNAME ) THEN
NB = 64
ELSE
NB = 32
END IF
ELSE IF( SUBNAM(2:6).EQ.'ORMRZ' ) THEN
NB = 64
ELSE IF( SUBNAM(2:6).EQ.'UNMRZ' ) THEN
NB = 32
ELSE IF( C2.EQ.'GE' ) THEN
IF( C3.EQ.'TRF' ) THEN
IF( SNAME ) THEN
-165
View File
@@ -1,165 +0,0 @@
/*****************************************************************************
Copyright (c) 2014, Intel Corp.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* 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.
* Neither the name of Intel Corporation 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.
*****************************************************************************
* Contents: Native middle-level C interface to LAPACK function cgesvdq
* Author: Intel Corporation
*****************************************************************************/
#include "lapacke_utils.h"
lapack_int LAPACKE_cgesvdq_work( int matrix_layout, char joba, char jobp,
char jobr, char jobu, char jobv,
lapack_int m, lapack_int n, lapack_complex_float* a,
lapack_int lda, float* s, lapack_complex_float* u, lapack_int ldu,
lapack_complex_float* v, lapack_int ldv, lapack_int* numrank,
lapack_int* iwork, lapack_int liwork,
lapack_complex_float* cwork, lapack_int lcwork,
float* rwork, lapack_int lrwork )
{
lapack_int info = 0;
if( matrix_layout == LAPACK_COL_MAJOR ) {
/* Call LAPACK function and adjust info */
LAPACK_cgesvdq( &joba, &jobp, &jobr, &jobu, &jobv, &m, &n, a, &lda, s, u, &ldu, v, &ldv,
numrank, iwork, &liwork, cwork, &lcwork, rwork, &lrwork, &info );
if( info < 0 ) {
info = info - 1;
}
} else if( matrix_layout == LAPACK_ROW_MAJOR ) {
lapack_int nrows_u = LAPACKE_lsame( jobu, 'a' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ||
LAPACKE_lsame( jobu, 's' ) ? m : 1;
lapack_int ncols_u = LAPACKE_lsame( jobu, 'a' ) ? m :
( LAPACKE_lsame( jobu, 's' ) ||
(LAPACKE_lsame( jobu, 'u' ) ) ? MIN(m,n) : 1);
lapack_int nrows_v = ( LAPACKE_lsame( jobv, 'a' ) ||
LAPACKE_lsame( jobv, 'v' ) ||
LAPACKE_lsame( jobv, 'r' )) ? n : 1;
lapack_int lda_t = MAX(1,m);
lapack_int ldu_t = MAX(1,nrows_u);
lapack_int ldv_t = MAX(1,nrows_v);
lapack_complex_float* a_t = NULL;
lapack_complex_float* u_t = NULL;
lapack_complex_float* v_t = NULL;
/* Check leading dimension(s) */
if( lda < n ) {
info = -9;
LAPACKE_xerbla( "LAPACKE_cgesvdq_work", info );
return info;
}
if( ldu < ncols_u ) {
info = -12;
LAPACKE_xerbla( "LAPACKE_cgesvdq_work", info );
return info;
}
if( ldv < n ) {
info = -14;
LAPACKE_xerbla( "LAPACKE_cgesvdq_work", info );
return info;
}
/* Query optimal working array(s) size if requested */
if( lcwork == -1 ) {
LAPACK_cgesvdq( &joba, &jobp, &jobr, &jobu, &jobv, &m, &n, a, &lda_t,
s, u, &ldu_t, v, &ldv_t, numrank, iwork, &liwork,
cwork, &lcwork, rwork, &lrwork, &info );
return (info < 0) ? (info - 1) : info;
}
/* Allocate memory for temporary array(s) */
a_t = (lapack_complex_float*)LAPACKE_malloc( sizeof(lapack_complex_float) * lda_t * MAX(1,n) );
if( a_t == NULL ) {
info = LAPACK_TRANSPOSE_MEMORY_ERROR;
goto exit_level_0;
}
if( LAPACKE_lsame( jobu, 'a' ) || LAPACKE_lsame( jobu, 's' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ) {
u_t = (lapack_complex_float*)
LAPACKE_malloc( sizeof(lapack_complex_float) * ldu_t * MAX(1,ncols_u) );
if( u_t == NULL ) {
info = LAPACK_TRANSPOSE_MEMORY_ERROR;
goto exit_level_1;
}
}
if( LAPACKE_lsame( jobv, 'a' ) || LAPACKE_lsame( jobv, 'v' ) ||
LAPACKE_lsame( jobv, 'r' ) ) {
v_t = (lapack_complex_float*)
LAPACKE_malloc( sizeof(lapack_complex_float) * ldv_t * MAX(1,n) );
if( v_t == NULL ) {
info = LAPACK_TRANSPOSE_MEMORY_ERROR;
goto exit_level_2;
}
}
/* Transpose input matrices */
LAPACKE_cge_trans( matrix_layout, m, n, a, lda, a_t, lda_t );
/* Call LAPACK function and adjust info */
LAPACK_cgesvdq( &joba, &jobp, &jobr, &jobu, &jobv, &m, &n, a, &lda_t,
s, u, &ldu_t, v, &ldv_t, numrank, iwork, &liwork,
cwork, &lcwork, rwork, &lrwork, &info );
if( info < 0 ) {
info = info - 1;
}
/* Transpose output matrices */
LAPACKE_cge_trans( LAPACK_COL_MAJOR, m, n, a_t, lda_t, a, lda );
if( LAPACKE_lsame( jobu, 'a' ) ||LAPACKE_lsame( jobu, 's' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ) {
LAPACKE_cge_trans( LAPACK_COL_MAJOR, nrows_u, ncols_u, u_t, ldu_t,
u, ldu );
}
if( LAPACKE_lsame( jobv, 'a' ) || LAPACKE_lsame( jobv, 'v' ) ||
LAPACKE_lsame( jobv, 'r' )) {
LAPACKE_cge_trans( LAPACK_COL_MAJOR, nrows_v, n, v_t, ldv_t, v,
ldv );
}
/* Release memory and exit */
if( LAPACKE_lsame( jobv, 'a' ) || LAPACKE_lsame( jobv, 'v' ) ||
LAPACKE_lsame( jobv, 'r' ) ) {
LAPACKE_free( v_t );
}
exit_level_2:
if( LAPACKE_lsame( jobu, 'a' ) || LAPACKE_lsame( jobu, 's' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ) {
LAPACKE_free( u_t );
}
exit_level_1:
LAPACKE_free( a_t );
exit_level_0:
if( info == LAPACK_TRANSPOSE_MEMORY_ERROR ) {
LAPACKE_xerbla( "LAPACKE_cgesvdq_work", info );
}
} else {
info = -1;
LAPACKE_xerbla( "LAPACKE_cgesvdq_work", info );
}
return info;
}
-165
View File
@@ -1,165 +0,0 @@
/*****************************************************************************
Copyright (c) 2014, Intel Corp.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* 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.
* Neither the name of Intel Corporation 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.
*****************************************************************************
* Contents: Native middle-level C interface to LAPACK function dgesvdq
* Author: Intel Corporation
*****************************************************************************/
#include "lapacke_utils.h"
lapack_int LAPACKE_dgesvdq_work( int matrix_layout, char joba, char jobp,
char jobr, char jobu, char jobv,
lapack_int m, lapack_int n, double* a,
lapack_int lda, double* s, double* u, lapack_int ldu,
double* v, lapack_int ldv, lapack_int* numrank,
lapack_int* iwork, lapack_int liwork,
double* work, lapack_int lwork,
double* rwork, lapack_int lrwork )
{
lapack_int info = 0;
if( matrix_layout == LAPACK_COL_MAJOR ) {
/* Call LAPACK function and adjust info */
LAPACK_dgesvdq( &joba, &jobp, &jobr, &jobu, &jobv, &m, &n, a, &lda, s, u, &ldu, v, &ldv,
numrank, iwork, &liwork, work, &lwork, rwork, &lrwork, &info );
if( info < 0 ) {
info = info - 1;
}
} else if( matrix_layout == LAPACK_ROW_MAJOR ) {
lapack_int nrows_u = ( LAPACKE_lsame( jobu, 'a' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ||
LAPACKE_lsame( jobu, 's' ) ) ? m : 1;
lapack_int ncols_u = LAPACKE_lsame( jobu, 'a' ) ? m :
( (LAPACKE_lsame( jobu, 's' ) ||
LAPACKE_lsame( jobu, 'u' ) ) ? MIN(m,n) : 1);
lapack_int nrows_v = ( LAPACKE_lsame( jobv, 'a' ) ||
LAPACKE_lsame( jobu, 'v' ) ||
LAPACKE_lsame( jobu, 'r' )) ? n : 1;
lapack_int lda_t = MAX(1,m);
lapack_int ldu_t = MAX(1,nrows_u);
lapack_int ldv_t = MAX(1,nrows_v);
double* a_t = NULL;
double* u_t = NULL;
double* v_t = NULL;
/* Check leading dimension(s) */
if( lda < n ) {
info = -9;
LAPACKE_xerbla( "LAPACKE_dgesvdq_work", info );
return info;
}
if( ldu < ncols_u ) {
info = -12;
LAPACKE_xerbla( "LAPACKE_dgesvdq_work", info );
return info;
}
if( ldv < n ) {
info = -14;
LAPACKE_xerbla( "LAPACKE_dgesvdq_work", info );
return info;
}
/* Query optimal working array(s) size if requested */
if( lwork == -1 ) {
LAPACK_dgesvdq( &joba, &jobp, &jobr, &jobu, &jobv, &m, &n, a, &lda_t,
s, u, &ldu_t, v, &ldv_t, numrank, iwork, &liwork,
work, &lwork, rwork, &lrwork, &info );
return (info < 0) ? (info - 1) : info;
}
/* Allocate memory for temporary array(s) */
a_t = (double*)LAPACKE_malloc( sizeof(double) * lda_t * MAX(1,n) );
if( a_t == NULL ) {
info = LAPACK_TRANSPOSE_MEMORY_ERROR;
goto exit_level_0;
}
if( LAPACKE_lsame( jobu, 'a' ) || LAPACKE_lsame( jobu, 's' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ) {
u_t = (double*)
LAPACKE_malloc( sizeof(double) * ldu_t * MAX(1,ncols_u) );
if( u_t == NULL ) {
info = LAPACK_TRANSPOSE_MEMORY_ERROR;
goto exit_level_1;
}
}
if( LAPACKE_lsame( jobv, 'a' ) || LAPACKE_lsame( jobv, 'v' ) ||
LAPACKE_lsame( jobu, 'r' ) ) {
v_t = (double*)
LAPACKE_malloc( sizeof(double) * ldv_t * MAX(1,n) );
if( v_t == NULL ) {
info = LAPACK_TRANSPOSE_MEMORY_ERROR;
goto exit_level_2;
}
}
/* Transpose input matrices */
LAPACKE_dge_trans( matrix_layout, m, n, a, lda, a_t, lda_t );
/* Call LAPACK function and adjust info */
LAPACK_dgesvdq( &joba, &jobp, &jobr, &jobu, &jobv, &m, &n, a, &lda_t,
s, u, &ldu_t, v, &ldv_t, numrank, iwork, &liwork,
work, &lwork, rwork, &lrwork, &info );
if( info < 0 ) {
info = info - 1;
}
/* Transpose output matrices */
LAPACKE_dge_trans( LAPACK_COL_MAJOR, m, n, a_t, lda_t, a, lda );
if( LAPACKE_lsame( jobu, 'a' ) || LAPACKE_lsame( jobu, 's' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ) {
LAPACKE_dge_trans)( LAPACK_COL_MAJOR, nrows_u, ncols_u, u_t, ldu_t,
u, ldu );
}
if( LAPACKE_lsame( jobv, 'a' ) || LAPACKE_lsame( jobv, 'v' ) ||
LAPACKE_lsame( jobu, 'r' )) {
LAPACKE_dge_trans( LAPACK_COL_MAJOR, nrows_v, n, v_t, ldv_t, v,
ldv );
}
/* Release memory and exit */
if( LAPACKE_lsame( jobv, 'a' ) || LAPACKE_lsame( jobv, 'v' ) ||
LAPACKE_lsame( jobu, 'r' ) ) {
LAPACKE_free( v_t );
}
exit_level_2:
if( LAPACKE_lsame( jobu, 'a' ) || LAPACKE_lsame( jobu, 's' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ) {
LAPACKE_free( u_t );
}
exit_level_1:
LAPACKE_free( a_t );
exit_level_0:
if( info == LAPACK_TRANSPOSE_MEMORY_ERROR ) {
LAPACKE_xerbla( "LAPACKE_dgesvdq_work", info );
}
} else {
info = -1;
LAPACKE_xerbla( "LAPACKE_dgesvdq_work", info );
}
return info;
}
-165
View File
@@ -1,165 +0,0 @@
/*****************************************************************************
Copyright (c) 2014, Intel Corp.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* 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.
* Neither the name of Intel Corporation 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.
*****************************************************************************
* Contents: Native middle-level C interface to LAPACK function sgesvdq
* Author: Intel Corporation
*****************************************************************************/
#include "lapacke_utils.h"
lapack_int LAPACKE_sgesvdq_work( int matrix_layout, char joba, char jobp,
char jobr, char jobu, char jobv,
lapack_int m, lapack_int n, float* a,
lapack_int lda, float* s, float* u, lapack_int ldu,
float* v, lapack_int ldv, lapack_int* numrank,
lapack_int* iwork, lapack_int liwork,
float* work, lapack_int lwork,
float* rwork, lapack_int lrwork )
{
lapack_int info = 0;
if( matrix_layout == LAPACK_COL_MAJOR ) {
/* Call LAPACK function and adjust info */
LAPACK_sgesvdq( &joba, &jobp, &jobr, &jobu, &jobv, &m, &n, a, &lda, s, u, &ldu, v, &ldv,
numrank, iwork, &liwork, work, &lwork, rwork, &lrwork, &info );
if( info < 0 ) {
info = info - 1;
}
} else if( matrix_layout == LAPACK_ROW_MAJOR ) {
lapack_int nrows_u = ( LAPACKE_lsame( jobu, 'a' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ||
LAPACKE_lsame( jobu, 's' ) ) ? m : 1;
lapack_int ncols_u = LAPACKE_lsame( jobu, 'a' ) ? m :
( (LAPACKE_lsame( jobu, 's' ) ||
LAPACKE_lsame( jobu, 'u' ) ) ? MIN(m,n) : 1);
lapack_int nrows_v = ( LAPACKE_lsame( jobv, 'a' ) ||
LAPACKE_lsame( jobv, 'v' ) ||
LAPACKE_lsame( jobv, 'r' )) ? n : 1;
lapack_int lda_t = MAX(1,m);
lapack_int ldu_t = MAX(1,nrows_u);
lapack_int ldv_t = MAX(1,nrows_v);
float* a_t = NULL;
float* u_t = NULL;
float* v_t = NULL;
/* Check leading dimension(s) */
if( lda < n ) {
info = -9;
LAPACKE_xerbla( "LAPACKE_sgesvdq_work", info );
return info;
}
if( ldu < ncols_u ) {
info = -12;
LAPACKE_xerbla( "LAPACKE_sgesvdq_work", info );
return info;
}
if( ldv < n ) {
info = -14;
LAPACKE_xerbla( "LAPACKE_sgesvdq_work", info );
return info;
}
/* Query optimal working array(s) size if requested */
if( lwork == -1 ) {
LAPACK_sgesvdq( &joba, &jobp, &jobr, &jobu, &jobv, &m, &n, a, &lda_t,
s, u, &ldu_t, v, &ldv_t, numrank, iwork, &liwork,
work, &lwork, rwork, &lrwork, &info );
return (info < 0) ? (info - 1) : info;
}
/* Allocate memory for temporary array(s) */
a_t = (float*)LAPACKE_malloc( sizeof(float) * lda_t * MAX(1,n) );
if( a_t == NULL ) {
info = LAPACK_TRANSPOSE_MEMORY_ERROR;
goto exit_level_0;
}
if( LAPACKE_lsame( jobu, 'a' ) || LAPACKE_lsame( jobu, 's' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ) {
u_t = (float*)
LAPACKE_malloc( sizeof(float) * ldu_t * MAX(1,ncols_u) );
if( u_t == NULL ) {
info = LAPACK_TRANSPOSE_MEMORY_ERROR;
goto exit_level_1;
}
}
if( LAPACKE_lsame( jobv, 'a' ) || LAPACKE_lsame( jobv, 'v' ) ||
LAPACKE_lsame( jobv, 'r' ) ) {
v_t = (float*)
LAPACKE_malloc( sizeof(float) * ldv_t * MAX(1,n) );
if( v_t == NULL ) {
info = LAPACK_TRANSPOSE_MEMORY_ERROR;
goto exit_level_2;
}
}
/* Transpose input matrices */
LAPACKE_sge_trans( matrix_layout, m, n, a, lda, a_t, lda_t );
/* Call LAPACK function and adjust info */
LAPACK_sgesvdq( &joba, &jobp, &jobr, &jobu, &jobv, &m, &n, a, &lda_t,
s, u, &ldu_t, v, &ldv_t, numrank, iwork, &liwork,
work, &lwork, rwork, &lrwork, &info );
if( info < 0 ) {
info = info - 1;
}
/* Transpose output matrices */
LAPACKE_sge_trans( LAPACK_COL_MAJOR, m, n, a_t, lda_t, a, lda );
if( LAPACKE_lsame( jobu, 'a' ) || LAPACKE_lsame( jobu, 's' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ) {
LAPACKE_sge_trans( LAPACK_COL_MAJOR, nrows_u, ncols_u, u_t, ldu_t,
u, ldu );
}
if( LAPACKE_lsame( jobv, 'a' ) || LAPACKE_lsame( jobv, 'v' ) ||
LAPACKE_lsame( jobv, 'r' )) {
LAPACKE_sge_trans( LAPACK_COL_MAJOR, nrows_v, n, v_t, ldv_t, v,
ldv );
}
/* Release memory and exit */
if( LAPACKE_lsame( jobv, 'a' ) || LAPACKE_lsame( jobv, 'v' ) ||
LAPACKE_lsame( jobv, 'r' ) ) {
LAPACKE_free( v_t );
}
exit_level_2:
if( LAPACKE_lsame( jobu, 'a' ) || LAPACKE_lsame( jobu, 's' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ) {
LAPACKE_free( u_t );
}
exit_level_1:
LAPACKE_free( a_t );
exit_level_0:
if( info == LAPACK_TRANSPOSE_MEMORY_ERROR ) {
LAPACKE_xerbla( "LAPACKE_sgesvdq_work", info );
}
} else {
info = -1;
LAPACKE_xerbla( "LAPACKE_sgesvdq_work", info );
}
return info;
}
-165
View File
@@ -1,165 +0,0 @@
/*****************************************************************************
Copyright (c) 2014, Intel Corp.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* 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.
* Neither the name of Intel Corporation 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.
*****************************************************************************
* Contents: Native middle-level C interface to LAPACK function zgesvdq
* Author: Intel Corporation
*****************************************************************************/
#include "lapacke_utils.h"
lapack_int LAPACKE_zgesvdq_work( int matrix_layout, char joba, char jobp,
char jobr, char jobu, char jobv,
lapack_int m, lapack_int n, lapack_complex_double* a,
lapack_int lda, double* s, lapack_complex_double* u, lapack_int ldu,
lapack_complex_double* v, lapack_int ldv, lapack_int* numrank,
lapack_int* iwork, lapack_int liwork,
lapack_complex_double* cwork, lapack_int lcwork,
double* rwork, lapack_int lrwork )
{
lapack_int info = 0;
if( matrix_layout == LAPACK_COL_MAJOR ) {
/* Call LAPACK function and adjust info */
LAPACK_zgesvdq( &joba, &jobp, &jobr, &jobu, &jobv, &m, &n, a, &lda, s, u, &ldu, v, &ldv,
numrank, iwork, &liwork, cwork, &lcwork, rwork, &lrwork, &info );
if( info < 0 ) {
info = info - 1;
}
} else if( matrix_layout == LAPACK_ROW_MAJOR ) {
lapack_int nrows_u = ( LAPACKE_lsame( jobu, 'a' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ||
LAPACKE_lsame( jobu, 's' ) ) ? m : 1;
lapack_int ncols_u = LAPACKE_lsame( jobu, 'a' ) ? m :
( (LAPACKE_lsame( jobu, 's' ) ||
LAPACKE_lsame( jobu, 'u' ) ) ? MIN(m,n) : 1);
lapack_int nrows_v = ( LAPACKE_lsame( jobv, 'a' ) ||
LAPACKE_lsame( jobv, 'v' ) ||
LAPACKE_lsame( jobv, 'r' )) ? n : 1;
lapack_int lda_t = MAX(1,m);
lapack_int ldu_t = MAX(1,nrows_u);
lapack_int ldv_t = MAX(1,nrows_v);
lapack_complex_double* a_t = NULL;
lapack_complex_double* u_t = NULL;
lapack_complex_double* v_t = NULL;
/* Check leading dimension(s) */
if( lda < n ) {
info = -9;
LAPACKE_xerbla( "LAPACKE_zgesvdq_work", info );
return info;
}
if( ldu < ncols_u ) {
info = -12;
LAPACKE_xerbla( "LAPACKE_zgesvdq_work", info );
return info;
}
if( ldv < n ) {
info = -14;
LAPACKE_xerbla( "LAPACKE_zgesvdq_work", info );
return info;
}
/* Query optimal working array(s) size if requested */
if( lcwork == -1 ) {
LAPACK_zgesvdq( &joba, &jobp, &jobr, &jobu, &jobv, &m, &n, a, &lda_t,
s, u, &ldu_t, v, &ldv_t, numrank, iwork, &liwork,
cwork, &lcwork, rwork, &lrwork, &info );
return (info < 0) ? (info - 1) : info;
}
/* Allocate memory for temporary array(s) */
a_t = (lapack_complex_double*)LAPACKE_malloc( sizeof(lapack_complex_double) * lda_t * MAX(1,n) );
if( a_t == NULL ) {
info = LAPACK_TRANSPOSE_MEMORY_ERROR;
goto exit_level_0;
}
if( LAPACKE_lsame( jobu, 'a' ) || LAPACKE_lsame( jobu, 's' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ) {
u_t = (lapack_complex_double*)
LAPACKE_malloc( sizeof(lapack_complex_double) * ldu_t * MAX(1,ncols_u) );
if( u_t == NULL ) {
info = LAPACK_TRANSPOSE_MEMORY_ERROR;
goto exit_level_1;
}
}
if( LAPACKE_lsame( jobv, 'a' ) || LAPACKE_lsame( jobv, 'v' ) ||
LAPACKE_lsame( jobv, 'r' ) ) {
v_t = (lapack_complex_double*)
LAPACKE_malloc( sizeof(lapack_complex_double) * ldv_t * MAX(1,n) );
if( v_t == NULL ) {
info = LAPACK_TRANSPOSE_MEMORY_ERROR;
goto exit_level_2;
}
}
/* Transpose input matrices */
LAPACKE_zge_trans( matrix_layout, m, n, a, lda, a_t, lda_t );
/* Call LAPACK function and adjust info */
LAPACK_zgesvdq( &joba, &jobp, &jobr, &jobu, &jobv, &m, &n, a, &lda_t,
s, u, &ldu_t, v, &ldv_t, numrank, iwork, &liwork,
cwork, &lcwork, rwork, &lrwork, &info );
if( info < 0 ) {
info = info - 1;
}
/* Transpose output matrices */
LAPACKE_zge_trans( LAPACK_COL_MAJOR, m, n, a_t, lda_t, a, lda );
if( LAPACKE_lsame( jobu, 'a' ) || LAPACKE_lsame( jobu, 's' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ) {
LAPACKE_zge_trans( LAPACK_COL_MAJOR, nrows_u, ncols_u, u_t, ldu_t,
u, ldu );
}
if( LAPACKE_lsame( jobv, 'a' ) || LAPACKE_lsame( jobv, 'v' ) ||
LAPACKE_lsame( jobv, 'r' )) {
LAPACKE_zge_trans( LAPACK_COL_MAJOR, nrows_v, n, v_t, ldv_t, v,
ldv );
}
/* Release memory and exit */
if( LAPACKE_lsame( jobv, 'a' ) || LAPACKE_lsame( jobv, 'v' ) ||
LAPACKE_lsame( jobv, 'r' ) ) {
LAPACKE_free( v_t );
}
exit_level_2:
if( LAPACKE_lsame( jobu, 'a' ) || LAPACKE_lsame( jobu, 's' ) ||
LAPACKE_lsame( jobu, 'u' ) ||
LAPACKE_lsame( jobu, 'r' ) ||
LAPACKE_lsame( jobu, 'f' ) ) {
LAPACKE_free( u_t );
}
exit_level_1:
LAPACKE_free( a_t );
exit_level_0:
if( info == LAPACK_TRANSPOSE_MEMORY_ERROR ) {
LAPACKE_xerbla( "LAPACKE_zgesvdq_work", info );
}
} else {
info = -1;
LAPACKE_xerbla( "LAPACKE_zgesvdq_work", info );
}
return info;
}
+3 -4
View File
@@ -351,9 +351,9 @@
* .. Parameters ..
INTEGER MAXITR
PARAMETER ( MAXITR = 6 )
REAL HUNDRED, MEIGHTH, ONE, TEN, ZERO
REAL HUNDRED, MEIGHTH, ZERO, ONE, TEN
PARAMETER ( HUNDRED = 100.0E0, MEIGHTH = -0.125E0,
$ ONE = 1.0E0, TEN = 10.0E0, ZERO = 0.0E0 )
$ ZERO = 0.0E0, ONE = 1.0E0, TEN = 10.0E0 )
REAL NEGONE
PARAMETER ( NEGONE = -1.0E0 )
REAL PIOVER2
@@ -576,7 +576,7 @@
END IF
ELSE
NU = SIGMA21
MU = SQRT( 1.0 - NU**2 )
MU = SQRT( ONE - NU**2 )
IF( NU .LT. THRESH ) THEN
MU = ONE
NU = ZERO
@@ -1108,4 +1108,3 @@
* End of SBBCSD
*
END
+25 -16
View File
@@ -5,7 +5,6 @@
* Online html documentation available at
* http://www.netlib.org/lapack/explore-html/
*
*> \htmlonly
*> Download SGELSY + dependencies
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/sgelsy.f">
*> [TGZ]</a>
@@ -13,7 +12,6 @@
*> [ZIP]</a>
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/sgelsy.f">
*> [TXT]</a>
*> \endhtmlonly
*
* Definition:
* ===========
@@ -201,8 +199,10 @@
*> G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain \n
*>
* =====================================================================
SUBROUTINE SGELSY( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
SUBROUTINE SGELSY( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND,
$ RANK,
$ WORK, LWORK, INFO )
IMPLICIT NONE
*
* -- LAPACK driver routine --
* -- LAPACK is a software package provided by Univ. of Tennessee, --
@@ -235,10 +235,12 @@
* .. External Functions ..
INTEGER ILAENV
REAL SLAMCH, SLANGE, SROUNDUP_LWORK
EXTERNAL ILAENV, SLAMCH, SLANGE, SROUNDUP_LWORK
EXTERNAL ILAENV, SLAMCH, SLANGE,
$ SROUNDUP_LWORK
* ..
* .. External Subroutines ..
EXTERNAL SCOPY, SGEQP3, SLAIC1, SLASCL, SLASET,
EXTERNAL SCOPY, SGEQP3, SLAIC1, SLASCL,
$ SLASET,
$ SORMQR, SORMRZ, STRSM, STZRZF, XERBLA
* ..
* .. Intrinsic Functions ..
@@ -274,9 +276,9 @@
LWKOPT = 1
ELSE
NB1 = ILAENV( 1, 'SGEQRF', ' ', M, N, -1, -1 )
NB2 = ILAENV( 1, 'SGERQF', ' ', M, N, -1, -1 )
NB2 = ILAENV( 1, 'STZRZF', ' ', M, N, -1, -1 )
NB3 = ILAENV( 1, 'SORMQR', ' ', M, N, NRHS, -1 )
NB4 = ILAENV( 1, 'SORMRQ', ' ', M, N, NRHS, -1 )
NB4 = ILAENV( 1, 'SORMRZ', ' ', M, N, NRHS, -1 )
NB = MAX( NB1, NB2, NB3, NB4 )
LWKMIN = MN + MAX( 2*MN, N + 1, MN + NRHS )
LWKOPT = MAX( LWKMIN,
@@ -339,13 +341,15 @@
*
* Scale matrix norm up to SMLNUM
*
CALL SLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
CALL SLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB,
$ INFO )
IBSCL = 1
ELSE IF( BNRM.GT.BIGNUM ) THEN
*
* Scale matrix norm down to BIGNUM
*
CALL SLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
CALL SLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB,
$ INFO )
IBSCL = 2
END IF
*
@@ -354,7 +358,7 @@
*
CALL SGEQP3( M, N, A, LDA, JPVT, WORK( 1 ), WORK( MN+1 ),
$ LWORK-MN, INFO )
WSIZE = MN + WORK( MN+1 )
WSIZE = REAL( MN ) + WORK( MN+1 )
*
* workspace: MN+2*N+NB*(N+1).
* Details of Householder rotations stored in WORK(1:MN).
@@ -412,9 +416,10 @@
*
* B(1:M,1:NRHS) := Q**T * B(1:M,1:NRHS)
*
CALL SORMQR( 'Left', 'Transpose', M, NRHS, MN, A, LDA, WORK( 1 ),
CALL SORMQR( 'Left', 'Transpose', M, NRHS, MN, A, LDA,
$ WORK( 1 ),
$ B, LDB, WORK( 2*MN+1 ), LWORK-2*MN, INFO )
WSIZE = MAX( WSIZE, 2*MN+WORK( 2*MN+1 ) )
WSIZE = MAX( WSIZE, REAL( 2*MN )+WORK( 2*MN+1 ) )
*
* workspace: 2*MN+NB*NRHS.
*
@@ -453,18 +458,22 @@
* Undo scaling
*
IF( IASCL.EQ.1 ) THEN
CALL SLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
CALL SLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB,
$ INFO )
CALL SLASCL( 'U', 0, 0, SMLNUM, ANRM, RANK, RANK, A, LDA,
$ INFO )
ELSE IF( IASCL.EQ.2 ) THEN
CALL SLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
CALL SLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB,
$ INFO )
CALL SLASCL( 'U', 0, 0, BIGNUM, ANRM, RANK, RANK, A, LDA,
$ INFO )
END IF
IF( IBSCL.EQ.1 ) THEN
CALL SLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
CALL SLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB,
$ INFO )
ELSE IF( IBSCL.EQ.2 ) THEN
CALL SLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
CALL SLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB,
$ INFO )
END IF
*
70 CONTINUE
+4 -4
View File
@@ -427,10 +427,10 @@
* the statistically correct thing to do in this situation is
* simply to iterate again.
* N.B. the case X( I ) = 0.0 should not be possible.
I1 = I1 + 2
I2 = I2 + 2
I3 = I3 + 2
I4 = I4 + 2
I1 = IT1
I2 = IT2
I3 = IT3
I4 = IT4
GOTO 20
END IF
*
+5 -3
View File
@@ -409,17 +409,19 @@
* ..
* .. External Functions ..
LOGICAL LSAME
EXTERNAL LSAME
REAL SLAMCH
EXTERNAL LSAME, SLAMCH
* ..
* .. External Subroutines ..
EXTERNAL SCOPY, SLAGS2, SLAPLL, SLARTG, SLASET, SROT,
$ SSCAL, XERBLA
* ..
* .. Intrinsic Functions ..
INTRINSIC ABS, MAX, MIN, HUGE
PARAMETER ( HUGENUM = HUGE(ZERO) )
INTRINSIC ABS, MAX, MIN
* ..
* .. Executable Statements ..
*
HUGENUM = SLAMCH( 'O' )
*
* Decode and test the input parameters
*
+3 -4
View File
@@ -351,9 +351,9 @@
* .. Parameters ..
INTEGER MAXITR
PARAMETER ( MAXITR = 6 )
DOUBLE PRECISION HUNDRED, MEIGHTH, ONE, TEN, ZERO
DOUBLE PRECISION HUNDRED, MEIGHTH, ZERO, ONE, TEN
PARAMETER ( HUNDRED = 100.0D0, MEIGHTH = -0.125D0,
$ ONE = 1.0D0, TEN = 10.0D0, ZERO = 0.0D0 )
$ ZERO = 0.0D0, ONE = 1.0D0, TEN = 10.0D0 )
COMPLEX*16 NEGONECOMPLEX
PARAMETER ( NEGONECOMPLEX = (-1.0D0,0.0D0) )
DOUBLE PRECISION PIOVER2
@@ -575,7 +575,7 @@
END IF
ELSE
NU = SIGMA21
MU = SQRT( 1.0 - NU**2 )
MU = SQRT( ONE - NU**2 )
IF( NU .LT. THRESH ) THEN
MU = ONE
NU = ZERO
@@ -1113,4 +1113,3 @@
* End of ZBBCSD
*
END
+22 -15
View File
@@ -5,7 +5,6 @@
* Online html documentation available at
* http://www.netlib.org/lapack/explore-html/
*
*> \htmlonly
*> Download ZGELSY + dependencies
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zgelsy.f">
*> [TGZ]</a>
@@ -13,7 +12,6 @@
*> [ZIP]</a>
*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zgelsy.f">
*> [TXT]</a>
*> \endhtmlonly
*
* Definition:
* ===========
@@ -197,7 +195,7 @@
*> \author Univ. of Colorado Denver
*> \author NAG Ltd.
*
*> \ingroup complex16GEsolve
*> \ingroup gelsy
*
*> \par Contributors:
* ==================
@@ -207,8 +205,10 @@
*> G. Quintana-Orti, Depto. de Informatica, Universidad Jaime I, Spain \n
*>
* =====================================================================
SUBROUTINE ZGELSY( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND, RANK,
SUBROUTINE ZGELSY( M, N, NRHS, A, LDA, B, LDB, JPVT, RCOND,
$ RANK,
$ WORK, LWORK, RWORK, INFO )
IMPLICIT NONE
*
* -- LAPACK driver routine --
* -- LAPACK is a software package provided by Univ. of Tennessee, --
@@ -244,7 +244,8 @@
COMPLEX*16 C1, C2, S1, S2
* ..
* .. External Subroutines ..
EXTERNAL DLABAD, XERBLA, ZCOPY, ZGEQP3, ZLAIC1, ZLASCL,
EXTERNAL XERBLA, ZCOPY, ZGEQP3, ZLAIC1,
$ ZLASCL,
$ ZLASET, ZTRSM, ZTZRZF, ZUNMQR, ZUNMRZ
* ..
* .. External Functions ..
@@ -265,9 +266,9 @@
*
INFO = 0
NB1 = ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
NB2 = ILAENV( 1, 'ZGERQF', ' ', M, N, -1, -1 )
NB2 = ILAENV( 1, 'ZTZRZF', ' ', M, N, -1, -1 )
NB3 = ILAENV( 1, 'ZUNMQR', ' ', M, N, NRHS, -1 )
NB4 = ILAENV( 1, 'ZUNMRQ', ' ', M, N, NRHS, -1 )
NB4 = ILAENV( 1, 'ZUNMRZ', ' ', M, N, NRHS, -1 )
NB = MAX( NB1, NB2, NB3, NB4 )
LWKOPT = MAX( 1, MN+2*N+NB*( N+1 ), 2*MN+NB*NRHS )
WORK( 1 ) = DCMPLX( LWKOPT )
@@ -305,7 +306,6 @@
*
SMLNUM = DLAMCH( 'S' ) / DLAMCH( 'P' )
BIGNUM = ONE / SMLNUM
CALL DLABAD( SMLNUM, BIGNUM )
*
* Scale A, B if max entries outside range [SMLNUM,BIGNUM]
*
@@ -338,13 +338,15 @@
*
* Scale matrix norm up to SMLNUM
*
CALL ZLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB, INFO )
CALL ZLASCL( 'G', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB,
$ INFO )
IBSCL = 1
ELSE IF( BNRM.GT.BIGNUM ) THEN
*
* Scale matrix norm down to BIGNUM
*
CALL ZLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB, INFO )
CALL ZLASCL( 'G', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB,
$ INFO )
IBSCL = 2
END IF
*
@@ -411,7 +413,8 @@
*
* B(1:M,1:NRHS) := Q**H * B(1:M,1:NRHS)
*
CALL ZUNMQR( 'Left', 'Conjugate transpose', M, NRHS, MN, A, LDA,
CALL ZUNMQR( 'Left', 'Conjugate transpose', M, NRHS, MN, A,
$ LDA,
$ WORK( 1 ), B, LDB, WORK( 2*MN+1 ), LWORK-2*MN, INFO )
WSIZE = MAX( WSIZE, 2*MN+DBLE( WORK( 2*MN+1 ) ) )
*
@@ -452,18 +455,22 @@
* Undo scaling
*
IF( IASCL.EQ.1 ) THEN
CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB, INFO )
CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB,
$ INFO )
CALL ZLASCL( 'U', 0, 0, SMLNUM, ANRM, RANK, RANK, A, LDA,
$ INFO )
ELSE IF( IASCL.EQ.2 ) THEN
CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB, INFO )
CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB,
$ INFO )
CALL ZLASCL( 'U', 0, 0, BIGNUM, ANRM, RANK, RANK, A, LDA,
$ INFO )
END IF
IF( IBSCL.EQ.1 ) THEN
CALL ZLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB, INFO )
CALL ZLASCL( 'G', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB,
$ INFO )
ELSE IF( IBSCL.EQ.2 ) THEN
CALL ZLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB, INFO )
CALL ZLASCL( 'G', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB,
$ INFO )
END IF
*
70 CONTINUE
+4 -4
View File
@@ -203,7 +203,7 @@ subroutine ZLARTG( f, g, c, s, r )
rtmax = rtmax * 2
if( f2 > rtmin .and. h2 < rtmax ) then
! safmin <= sqrt( f2*h2 ) <= safmax
s = conjg( g ) * ( f / sqrt( f2*h2 ) )
s = ( f / sqrt( f2 ) ) * ( conjg( g ) / sqrt( h2 ) )
else
s = conjg( g ) * ( r / h2 )
end if
@@ -223,7 +223,7 @@ subroutine ZLARTG( f, g, c, s, r )
! sqrt(safmin) <= f2 * sqrt(safmax) <= h2 / sqrt(f2 * h2) <= h2 * (safmin / f2) <= h2 <= safmax
r = f * ( h2 / d )
end if
s = conjg( g ) * ( f / d )
s = ( f / sqrt( f2 ) ) * ( conjg( g ) / sqrt( h2 ) )
end if
else
!
@@ -259,7 +259,7 @@ subroutine ZLARTG( f, g, c, s, r )
rtmax = rtmax * 2
if( f2 > rtmin .and. h2 < rtmax ) then
! safmin <= sqrt( f2*h2 ) <= safmax
s = conjg( gs ) * ( fs / sqrt( f2*h2 ) )
s = ( fs / sqrt( f2 ) ) * ( conjg( gs ) / sqrt( h2 ) )
else
s = conjg( gs ) * ( r / h2 )
end if
@@ -279,7 +279,7 @@ subroutine ZLARTG( f, g, c, s, r )
! sqrt(safmin) <= f2 * sqrt(safmax) <= h2 / sqrt(f2 * h2) <= h2 * (safmin / f2) <= h2 <= safmax
r = fs * ( h2 / d )
end if
s = conjg( gs ) * ( fs / d )
s = ( fs / sqrt( f2 ) ) * ( conjg( gs ) / sqrt( h2 ) )
end if
! Rescale c and r
c = c * w
+5 -3
View File
@@ -414,17 +414,19 @@
* ..
* .. External Functions ..
LOGICAL LSAME
EXTERNAL LSAME
DOUBLE PRECISION DLAMCH
EXTERNAL LSAME, DLAMCH
* ..
* .. External Subroutines ..
EXTERNAL DLARTG, XERBLA, ZCOPY, ZDSCAL, ZLAGS2, ZLAPLL,
$ ZLASET, ZROT
* ..
* .. Intrinsic Functions ..
INTRINSIC ABS, DBLE, DCONJG, MAX, MIN, HUGE
PARAMETER ( HUGENUM = HUGE(ZERO) )
INTRINSIC ABS, DBLE, DCONJG, MAX, MIN
* ..
* .. Executable Statements ..
*
HUGENUM = DLAMCH( 'O' )
*
* Decode and test the input parameters
*
+9 -2
View File
@@ -394,12 +394,19 @@
CALL CLACPY( 'Full', M, N, A, LDA, AF, LDA )
*
SRNAMT = 'CGELS'
CALL CGELS( 'No transpose', M, N, NRHS, AF,
CALL CGELS( 'No transpose', M, N, NRHS, AF,
$ LDA, X, LDA, WORK, LWORK, INFO )
*
* Re-factorize AF with CGELQF for subsequent
* LQ tests which expect LQ factorization in AF.
*
CALL CLACPY( 'Full', M, N, A, LDA, AF, LDA )
CALL CGELQF( M, N, AF, LDA, TAU, WORK,
$ LWORK, INFO )
*
* Check error code from CGELS.
*
IF( INFO.NE.0 )
IF( INFO.NE.0 )
$ CALL ALAERH( PATH, 'CGELS', INFO, 0, 'N',
$ M, N, NRHS, -1, NB, IMAT,
$ NFAIL, NERRS, NOUT )
+9 -2
View File
@@ -397,12 +397,19 @@
CALL DLACPY( 'Full', M, N, A, LDA, AF, LDA )
*
SRNAMT = 'DGELS'
CALL DGELS( 'No transpose', M, N, NRHS, AF,
CALL DGELS( 'No transpose', M, N, NRHS, AF,
$ LDA, X, LDA, WORK, LWORK, INFO )
*
* Re-factorize AF with DGELQF for subsequent
* LQ tests which expect LQ factorization in AF.
*
CALL DLACPY( 'Full', M, N, A, LDA, AF, LDA )
CALL DGELQF( M, N, AF, LDA, TAU, WORK,
$ LWORK, INFO )
*
* Check error code from DGELS.
*
IF( INFO.NE.0 )
IF( INFO.NE.0 )
$ CALL ALAERH( PATH, 'DGELS', INFO, 0, 'N',
$ M, N, NRHS, -1, NB, IMAT,
$ NFAIL, NERRS, NOUT )
+9 -2
View File
@@ -394,12 +394,19 @@
CALL SLACPY( 'Full', M, N, A, LDA, AF, LDA )
*
SRNAMT = 'SGELS'
CALL SGELS( 'No transpose', M, N, NRHS, AF,
CALL SGELS( 'No transpose', M, N, NRHS, AF,
$ LDA, X, LDA, WORK, LWORK, INFO )
*
* Re-factorize AF with SGELQF for subsequent
* LQ tests which expect LQ factorization in AF.
*
CALL SLACPY( 'Full', M, N, A, LDA, AF, LDA )
CALL SGELQF( M, N, AF, LDA, TAU, WORK,
$ LWORK, INFO )
*
* Check error code from SGELS.
*
IF( INFO.NE.0 )
IF( INFO.NE.0 )
$ CALL ALAERH( PATH, 'SGELS', INFO, 0, 'N',
$ M, N, NRHS, -1, NB, IMAT,
$ NFAIL, NERRS, NOUT )
+9 -2
View File
@@ -394,12 +394,19 @@
CALL ZLACPY( 'Full', M, N, A, LDA, AF, LDA )
*
SRNAMT = 'ZGELS'
CALL ZGELS( 'No transpose', M, N, NRHS, AF,
CALL ZGELS( 'No transpose', M, N, NRHS, AF,
$ LDA, X, LDA, WORK, LWORK, INFO )
*
* Re-factorize AF with ZGELQF for subsequent
* LQ tests which expect LQ factorization in AF.
*
CALL ZLACPY( 'Full', M, N, A, LDA, AF, LDA )
CALL ZGELQF( M, N, AF, LDA, TAU, WORK,
$ LWORK, INFO )
*
* Check error code from ZGELS.
*
IF( INFO.NE.0 )
IF( INFO.NE.0 )
$ CALL ALAERH( PATH, 'ZGELS', INFO, 0, 'N',
$ M, N, NRHS, -1, NB, IMAT,
$ NFAIL, NERRS, NOUT )
+60 -4
View File
@@ -3087,6 +3087,45 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
#if defined(U74)
#define GEMM_DEFAULT_OFFSET_A 0
#define GEMM_DEFAULT_OFFSET_B 0
#define GEMM_DEFAULT_ALIGN (BLASLONG)0x03fffUL
/* 4x4 register tile: 16 independent FMA accumulator chains hide the U74's
* 7-cycle fmadd.d latency (repeat rate 1); load:FMA ratio drops to 1:2. */
#define SGEMM_DEFAULT_UNROLL_M 4
#define SGEMM_DEFAULT_UNROLL_N 4
#define DGEMM_DEFAULT_UNROLL_M 4
#define DGEMM_DEFAULT_UNROLL_N 4
/* complex GEMM keeps the generic 2x2 kernel */
#define CGEMM_DEFAULT_UNROLL_M 2
#define CGEMM_DEFAULT_UNROLL_N 2
#define ZGEMM_DEFAULT_UNROLL_M 2
#define ZGEMM_DEFAULT_UNROLL_N 2
#define SGEMM_DEFAULT_P 128
#define DGEMM_DEFAULT_P 128
#define CGEMM_DEFAULT_P 96
#define ZGEMM_DEFAULT_P 64
#define SGEMM_DEFAULT_Q 240
#define DGEMM_DEFAULT_Q 256
#define CGEMM_DEFAULT_Q 120
#define ZGEMM_DEFAULT_Q 120
#define SGEMM_DEFAULT_R 12288
#define DGEMM_DEFAULT_R 8192
#define CGEMM_DEFAULT_R 4096
#define ZGEMM_DEFAULT_R 4096
#define SYMV_P 16
#endif
#if defined(x280)
#define GEMM_DEFAULT_OFFSET_A 0
#define GEMM_DEFAULT_OFFSET_B 0
@@ -3265,10 +3304,27 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define SHGEMM_DEFAULT_P 128
#undef SBGEMM_DEFAULT_P
#define SBGEMM_DEFAULT_P 128
#define SGEMM_DEFAULT_P 128
#define DGEMM_DEFAULT_P 64
#define CGEMM_DEFAULT_P 64
#define ZGEMM_DEFAULT_P 64
/* Base packed-A (P) blocking for this core. On static builds blas_set_parameter()
scales P from the L2 cache detected at runtime, relative to RISCV_L2_REFERENCE_KB
(the L2 size these bases target); Q and R keep their param.h defaults. A cache
equal to the reference reproduces the stock blocking. DYNAMIC_ARCH uses the
literals directly (kernel/setparam-ref.c fills the gotoblas table from them). */
#define RISCV_L2_REFERENCE_KB 512
#define SGEMM_DEFAULT_P_BASE 128
#define DGEMM_DEFAULT_P_BASE 64
#define CGEMM_DEFAULT_P_BASE 64
#define ZGEMM_DEFAULT_P_BASE 64
#if defined(DYNAMIC_ARCH)
#define SGEMM_DEFAULT_P SGEMM_DEFAULT_P_BASE
#define DGEMM_DEFAULT_P DGEMM_DEFAULT_P_BASE
#define CGEMM_DEFAULT_P CGEMM_DEFAULT_P_BASE
#define ZGEMM_DEFAULT_P ZGEMM_DEFAULT_P_BASE
#else
#define SGEMM_DEFAULT_P sgemm_p
#define DGEMM_DEFAULT_P dgemm_p
#define CGEMM_DEFAULT_P cgemm_p
#define ZGEMM_DEFAULT_P zgemm_p
#endif
#undef SHGEMM_DEFAULT_Q
#define SHGEMM_DEFAULT_Q 128
+46 -17
View File
@@ -31,9 +31,22 @@ if (USE_GEMM3M)
endif ()
endif ()
add_library(openblas_test_xerbla OBJECT xerbla_test.c)
# Static test executables provide their own XERBLA and must continue to test
# link-time interposition. Shared-only tests use the explicit handler because
# calls originating in a DLL or dylib cannot portably bind to that definition.
if (BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
target_compile_definitions(openblas_test_xerbla PRIVATE
OPENBLAS_TEST_USE_XERBLA_HANDLER)
endif()
foreach(test_bin ${OpenBLAS_Tests})
add_executable(${test_bin} ${test_bin}.f)
target_link_libraries(${test_bin} ${OpenBLAS_LIBNAME})
if (test_bin MATCHES "blat(2|3)(_3m)?$")
target_sources(${test_bin} PRIVATE
$<TARGET_OBJECTS:openblas_test_xerbla>)
endif()
target_link_libraries(${test_bin} ${OpenBLAS_LIBNAME})
endforeach()
if (BUILD_BFLOAT16)
@@ -62,29 +75,45 @@ endif()
if(WIN32)
FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/test_helper.ps1
"[Console]::InputEncoding = New-Object Text.UTF8Encoding $false\n"
"if (Test-Path $args[2]) { Remove-Item -Force $args[2] } \n"
"$ErrorActionPreference = \"Stop\"\n"
"Get-Content $args[1] | & $args[0]\n"
"If ((Get-Content $args[2] | %{$_ -match \"FATAL\"}) -contains $true) {\n"
"echo Error in $args[1]:\n"
"Get-Content $args[2] \n"
"exit 1\n"
"} else {\n"
"exit 0\n"
"if (Test-Path -LiteralPath $args[2]) { Remove-Item -LiteralPath $args[2] -Force }\n"
"Get-Content -LiteralPath $args[1] | & $args[0]\n"
"$testExitCode = $LASTEXITCODE\n"
"if ($testExitCode -ne 0) { exit $testExitCode }\n"
"if (-not (Test-Path -LiteralPath $args[2])) {\n"
" Write-Host \"Missing test summary: $($args[2])\"\n"
" exit 1\n"
"}\n"
"if (Select-String -LiteralPath $args[2] -Pattern \"FATAL|FAILED\" -Quiet) {\n"
" Write-Host \"Error in $($args[1]):\"\n"
" Get-Content -LiteralPath $args[2]\n"
" exit 1\n"
"}\n"
"exit 0\n"
)
set(helper_prefix powershell -ExecutionPolicy Bypass "${CMAKE_CURRENT_BINARY_DIR}/test_helper.ps1")
else()
FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/test_helper.sh
"rm -f $3\n"
"$1 < $2\n"
"grep -q FATAL $3\n"
"if [ $? -eq 0 ]; then\n"
"echo Error\n"
"exit 1\n"
"else\n"
"exit 0\n"
"rm -f \"$3\"\n"
"remove_status=$?\n"
"if [ $remove_status -ne 0 ]; then\n"
" echo \"Unable to remove stale test summary: $3\"\n"
" exit $remove_status\n"
"fi\n"
"\"$1\" < \"$2\"\n"
"test_exit_code=$?\n"
"if [ $test_exit_code -ne 0 ]; then exit $test_exit_code; fi\n"
"if [ ! -f \"$3\" ]; then\n"
" echo \"Missing test summary: $3\"\n"
" exit 1\n"
"fi\n"
"grep -q -e FATAL -e FAILED \"$3\"\n"
"summary_status=$?\n"
"case $summary_status in\n"
" 0) echo \"Error in $2:\"; cat \"$3\"; exit 1 ;;\n"
" 1) exit 0 ;;\n"
" *) echo \"Unable to read test summary: $3\"; exit $summary_status ;;\n"
"esac\n"
)
set(helper_prefix sh "${CMAKE_CURRENT_BINARY_DIR}/test_helper.sh")
endif()
+81 -68
View File
@@ -37,6 +37,16 @@ endif
# override CFLAGS += -std=c11 -Wall -Werror
SUPPORT_GEMM3M = 0
XERBLA_TEST = xerbla_test.$(SUFFIX)
define CHECK_TEST_SUMMARY
@status=0; $(GREP) -q -e FATAL -e FAILED "$(1)" || status=$$?; \
case $$status in \
0) cat "$(1)"; exit 1 ;; \
1) ;; \
*) echo "Unable to read test summary: $(1)"; exit $$status ;; \
esac
endef
ifeq ($(ARCH), x86)
SUPPORT_GEMM3M = 1
@@ -146,85 +156,85 @@ ifneq ($(CROSS), 1)
rm -f ?BLAT2.SUMM
ifeq ($(BUILD_BFLOAT16),1)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./test_bgemv$(EXE) > BBLAT2.SUMM
@$(GREP) -q FATAL BBLAT2.SUMM && cat BBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,BBLAT2.SUMM)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./test_sbgemv$(EXE) > SBBLAT2.SUMM
@$(GREP) -q FATAL SBBLAT2.SUMM && cat SBBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SBBLAT2.SUMM)
endif
ifeq ($(BUILD_HFLOAT16),1)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./test_shgemv$(EXE) > SHBLAT2.SUMM
@$(GREP) -q FATAL SHBLAT2.SUMM && cat SHBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SHBLAT2.SUMM)
endif
ifeq ($(BUILD_SINGLE),1)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./sblat2$(EXE) < ./sblat2.dat
@$(GREP) -q FATAL SBLAT2.SUMM && cat SBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SBLAT2.SUMM)
endif
ifeq ($(BUILD_DOUBLE),1)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./dblat2$(EXE) < ./dblat2.dat
@$(GREP) -q FATAL DBLAT2.SUMM && cat DBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,DBLAT2.SUMM)
endif
ifeq ($(BUILD_COMPLEX),1)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./cblat2$(EXE) < ./cblat2.dat
@$(GREP) -q FATAL CBLAT2.SUMM && cat CBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,CBLAT2.SUMM)
endif
ifeq ($(BUILD_COMPLEX16),1)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./zblat2$(EXE) < ./zblat2.dat
@$(GREP) -q FATAL ZBLAT2.SUMM && cat ZBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,ZBLAT2.SUMM)
endif
ifdef SMP
rm -f ?BLAT2.SUMM
ifeq ($(USE_OPENMP), 1)
ifeq ($(BUILD_BFLOAT16),1)
OMP_NUM_THREADS=2 ./test_bgemv$(EXE) > BBLAT2.SUMM
@$(GREP) -q FATAL BBLAT2.SUMM && cat BBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,BBLAT2.SUMM)
OMP_NUM_THREADS=2 ./test_sbgemv$(EXE) > SBBLAT2.SUMM
@$(GREP) -q FATAL SBBLAT2.SUMM && cat SBBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SBBLAT2.SUMM)
endif
ifeq ($(BUILD_HFLOAT16),1)
OMP_NUM_THREADS=2 ./test_shgemv$(EXE) > SHBLAT2.SUMM
@$(GREP) -q FATAL SHBLAT2.SUMM && cat SHBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SHBLAT2.SUMM)
endif
ifeq ($(BUILD_SINGLE),1)
OMP_NUM_THREADS=2 ./sblat2$(EXE) < ./sblat2.dat
@$(GREP) -q FATAL SBLAT2.SUMM && cat SBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SBLAT2.SUMM)
endif
ifeq ($(BUILD_DOUBLE),1)
OMP_NUM_THREADS=2 ./dblat2$(EXE) < ./dblat2.dat
@$(GREP) -q FATAL DBLAT2.SUMM && cat DBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,DBLAT2.SUMM)
endif
ifeq ($(BUILD_COMPLEX),1)
OMP_NUM_THREADS=2 ./cblat2$(EXE) < ./cblat2.dat
@$(GREP) -q FATAL CBLAT2.SUMM && cat CBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,CBLAT2.SUMM)
endif
ifeq ($(BUILD_COMPLEX16),1)
OMP_NUM_THREADS=2 ./zblat2$(EXE) < ./zblat2.dat
@$(GREP) -q FATAL ZBLAT2.SUMM && cat ZBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,ZBLAT2.SUMM)
endif
else
ifeq ($(BUILD_BFLOAT16),1)
OMP_NUM_THREADS=2 ./test_bgemv$(EXE) > BBLAT2.SUMM
@$(GREP) -q FATAL BBLAT2.SUMM && cat BBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,BBLAT2.SUMM)
OMP_NUM_THREADS=2 ./test_sbgemv$(EXE) > SBBLAT2.SUMM
@$(GREP) -q FATAL SBBLAT2.SUMM && cat SBBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SBBLAT2.SUMM)
endif
ifeq ($(BUILD_HFLOAT16),1)
OMP_NUM_THREADS=2 ./test_shgemv$(EXE) > SHBLAT2.SUMM
@$(GREP) -q FATAL SHBLAT2.SUMM && cat SHBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SHBLAT2.SUMM)
endif
ifeq ($(BUILD_SINGLE),1)
OPENBLAS_NUM_THREADS=2 ./sblat2$(EXE) < ./sblat2.dat
@$(GREP) -q FATAL SBLAT2.SUMM && cat SBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SBLAT2.SUMM)
endif
ifeq ($(BUILD_DOUBLE),1)
OPENBLAS_NUM_THREADS=2 ./dblat2$(EXE) < ./dblat2.dat
@$(GREP) -q FATAL DBLAT2.SUMM && cat DBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,DBLAT2.SUMM)
endif
ifeq ($(BUILD_COMPLEX),1)
OPENBLAS_NUM_THREADS=2 ./cblat2$(EXE) < ./cblat2.dat
@$(GREP) -q FATAL CBLAT2.SUMM && cat CBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,CBLAT2.SUMM)
endif
ifeq ($(BUILD_COMPLEX16),1)
OPENBLAS_NUM_THREADS=2 ./zblat2$(EXE) < ./zblat2.dat
@$(GREP) -q FATAL ZBLAT2.SUMM && cat ZBLAT2.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,ZBLAT2.SUMM)
endif
endif
endif
@@ -273,86 +283,86 @@ ifneq ($(CROSS), 1)
rm -f ?BLAT3.SUMM
ifeq ($(BUILD_BFLOAT16),1)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./test_sbgemm$(EXE) > SBBLAT3.SUMM
@$(GREP) -q FATAL SBBLAT3.SUMM && cat SBBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SBBLAT3.SUMM)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./test_bgemm$(EXE) > BBLAT3.SUMM
@$(GREP) -q FATAL BBLAT3.SUMM && cat BBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,BBLAT3.SUMM)
endif
ifeq ($(BUILD_HFLOAT16),1)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./test_shgemm > SHBLAT3.SUMM
@$(GREP) -q FATAL SHBLAT3.SUMM && cat SHBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SHBLAT3.SUMM)
endif
ifeq ($(BUILD_SINGLE),1)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./sblat3$(EXE) < ./sblat3.dat
@$(GREP) -q FATAL SBLAT3.SUMM && cat SBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SBLAT3.SUMM)
endif
ifeq ($(BUILD_DOUBLE),1)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./dblat3$(EXE) < ./dblat3.dat
@$(GREP) -q FATAL DBLAT3.SUMM && cat DBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,DBLAT3.SUMM)
endif
ifeq ($(BUILD_COMPLEX),1)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./cblat3$(EXE) < ./cblat3.dat
@$(GREP) -q FATAL CBLAT3.SUMM && cat CBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,CBLAT3.SUMM)
endif
ifeq ($(BUILD_COMPLEX16),1)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./zblat3$(EXE) < ./zblat3.dat
@$(GREP) -q FATAL ZBLAT3.SUMM && cat ZBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,ZBLAT3.SUMM)
endif
ifdef SMP
rm -f ?BLAT3.SUMM
ifeq ($(USE_OPENMP), 1)
ifeq ($(BUILD_BFLOAT16),1)
OMP_NUM_THREADS=2 ./test_sbgemm$(EXE) > SBBLAT3.SUMM
@$(GREP) -q FATAL SBBLAT3.SUMM && cat SBBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SBBLAT3.SUMM)
OMP_NUM_THREADS=2 ./test_bgemm$(EXE) > BBLAT3.SUMM
@$(GREP) -q FATAL BBLAT3.SUMM && cat BBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,BBLAT3.SUMM)
endif
ifeq ($(BUILD_HFLOAT16),1)
OMP_NUM_THREADS=2 ./test_shgemm > SHBLAT3.SUMM
@$(GREP) -q FATAL SHBLAT3.SUMM && cat SHBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SHBLAT3.SUMM)
endif
ifeq ($(BUILD_SINGLE),1)
OMP_NUM_THREADS=2 ./sblat3$(EXE) < ./sblat3.dat
@$(GREP) -q FATAL SBLAT3.SUMM && cat SBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SBLAT3.SUMM)
endif
ifeq ($(BUILD_DOUBLE),1)
OMP_NUM_THREADS=2 ./dblat3$(EXE) < ./dblat3.dat
@$(GREP) -q FATAL DBLAT3.SUMM && cat DBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,DBLAT3.SUMM)
endif
ifeq ($(BUILD_COMPLEX),1)
OMP_NUM_THREADS=2 ./cblat3$(EXE) < ./cblat3.dat
@$(GREP) -q FATAL CBLAT3.SUMM && cat CBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,CBLAT3.SUMM)
endif
ifeq ($(BUILD_COMPLEX16),1)
OMP_NUM_THREADS=2 ./zblat3$(EXE) < ./zblat3.dat
@$(GREP) -q FATAL ZBLAT3.SUMM && cat ZBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,ZBLAT3.SUMM)
endif
else
ifeq ($(BUILD_BFLOAT16),1)
OPENBLAS_NUM_THREADS=2 ./test_sbgemm$(EXE) > SBBLAT3.SUMM
@$(GREP) -q FATAL SBBLAT3.SUMM && cat SBBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SBBLAT3.SUMM)
OPENBLAS_NUM_THREADS=2 ./test_bgemm$(EXE) > BBLAT3.SUMM
@$(GREP) -q FATAL BBLAT3.SUMM && cat BBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,BBLAT3.SUMM)
endif
ifeq ($(BUILD_HFLOAT16),1)
OPENBLAS_NUM_THREADS=2 ./test_shgemm > SHBLAT3.SUMM
@$(GREP) -q FATAL SHBLAT3.SUMM && cat SHBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SHBLAT3.SUMM)
endif
ifeq ($(BUILD_SINGLE),1)
OPENBLAS_NUM_THREADS=2 ./sblat3$(EXE) < ./sblat3.dat
@$(GREP) -q FATAL SBLAT3.SUMM && cat SBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,SBLAT3.SUMM)
endif
ifeq ($(BUILD_DOUBLE),1)
OPENBLAS_NUM_THREADS=2 ./dblat3$(EXE) < ./dblat3.dat
@$(GREP) -q FATAL DBLAT3.SUMM && cat DBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,DBLAT3.SUMM)
endif
ifeq ($(BUILD_COMPLEX),1)
OPENBLAS_NUM_THREADS=2 ./cblat3$(EXE) < ./cblat3.dat
@$(GREP) -q FATAL CBLAT3.SUMM && cat CBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,CBLAT3.SUMM)
endif
ifeq ($(BUILD_COMPLEX16),1)
OPENBLAS_NUM_THREADS=2 ./zblat3$(EXE) < ./zblat3.dat
@$(GREP) -q FATAL ZBLAT3.SUMM && cat ZBLAT3.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,ZBLAT3.SUMM)
endif
endif
endif
@@ -364,31 +374,31 @@ ifneq ($(CROSS), 1)
rm -f ?BLAT3_3M.SUMM
ifeq ($(BUILD_COMPLEX),1)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./cblat3_3m$(EXE) < ./cblat3_3m.dat
@$(GREP) -q FATAL CBLAT3_3M.SUMM && cat CBLAT3_3M.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,CBLAT3_3M.SUMM)
endif
ifeq ($(BUILD_COMPLEX16),1)
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 ./zblat3_3m$(EXE) < ./zblat3_3m.dat
@$(GREP) -q FATAL ZBLAT3_3M.SUMM && cat ZBLAT3_3M.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,ZBLAT3_3M.SUMM)
endif
ifdef SMP
rm -f ?BLAT3_3M.SUMM
ifeq ($(USE_OPENMP), 1)
ifeq ($(BUILD_COMPLEX),1)
OMP_NUM_THREADS=2 ./cblat3_3m$(EXE) < ./cblat3_3m.dat
@$(GREP) -q FATAL CBLAT3_3M.SUMM && cat CBLAT3_3M.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,CBLAT3_3M.SUMM)
endif
ifeq ($(BUILD_COMPLEX16),1)
OMP_NUM_THREADS=2 ./zblat3_3m$(EXE) < ./zblat3_3m.dat
@$(GREP) -q FATAL ZBLAT3_3M.SUMM && cat ZBLAT3_3M.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,ZBLAT3_3M.SUMM)
endif
else
ifeq ($(BUILD_COMPLEX),1)
OPENBLAS_NUM_THREADS=2 ./cblat3_3m$(EXE) < ./cblat3_3m.dat
@$(GREP) -q FATAL CBLAT3_3M.SUMM && cat CBLAT3_3M.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,CBLAT3_3M.SUMM)
endif
ifeq ($(BUILD_COMPLEX16),1)
OPENBLAS_NUM_THREADS=2 ./zblat3_3m$(EXE) < ./zblat3_3m.dat
@$(GREP) -q FATAL ZBLAT3_3M.SUMM && cat ZBLAT3_3M.SUMM || exit 0
$(call CHECK_TEST_SUMMARY,ZBLAT3_3M.SUMM)
endif
endif
endif
@@ -420,26 +430,29 @@ endif
endif
endif
$(XERBLA_TEST): xerbla_test.c
$(CC) $(CFLAGS) -c $< -o $@
ifeq ($(BUILD_SINGLE),1)
sblat1$(EXE) : sblat1.$(SUFFIX) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ sblat1.$(SUFFIX) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
sblat2$(EXE) : sblat2.$(SUFFIX) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ sblat2.$(SUFFIX) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
sblat2$(EXE) : sblat2.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ sblat2.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
sblat3$(EXE) : sblat3.$(SUFFIX) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ sblat3.$(SUFFIX) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
sblat3$(EXE) : sblat3.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ sblat3.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
endif
ifeq ($(BUILD_DOUBLE),1)
dblat1$(EXE) : dblat1.$(SUFFIX) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ dblat1.$(SUFFIX) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
dblat2$(EXE) : dblat2.$(SUFFIX) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ dblat2.$(SUFFIX) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
dblat2$(EXE) : dblat2.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ dblat2.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
dblat3$(EXE) : dblat3.$(SUFFIX) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ dblat3.$(SUFFIX) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
dblat3$(EXE) : dblat3.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ dblat3.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
else
dblat2$(EXE):
dblat3$(EXE):
@@ -453,22 +466,22 @@ ifeq ($(BUILD_COMPLEX),1)
cblat1$(EXE) : cblat1.$(SUFFIX) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ cblat1.$(SUFFIX) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
cblat2$(EXE) : cblat2.$(SUFFIX) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ cblat2.$(SUFFIX) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
cblat2$(EXE) : cblat2.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ cblat2.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
cblat3$(EXE) : cblat3.$(SUFFIX) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ cblat3.$(SUFFIX) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
cblat3$(EXE) : cblat3.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ cblat3.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
endif
ifeq ($(BUILD_COMPLEX16),1)
zblat1$(EXE) : zblat1.$(SUFFIX) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ zblat1.$(SUFFIX) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
zblat2$(EXE) : zblat2.$(SUFFIX) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ zblat2.$(SUFFIX) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
zblat2$(EXE) : zblat2.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ zblat2.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
zblat3$(EXE) : zblat3.$(SUFFIX) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ zblat3.$(SUFFIX) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
zblat3$(EXE) : zblat3.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ zblat3.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
endif
ifeq ($(BUILD_BFLOAT16),1)
@@ -495,13 +508,13 @@ endif
ifeq ($(BUILD_COMPLEX),1)
cblat3_3m$(EXE) : cblat3_3m.$(SUFFIX) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ cblat3_3m.$(SUFFIX) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
cblat3_3m$(EXE) : cblat3_3m.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ cblat3_3m.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
endif
ifeq ($(BUILD_COMPLEX16),1)
zblat3_3m$(EXE) : zblat3_3m.$(SUFFIX) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ zblat3_3m.$(SUFFIX) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
zblat3_3m$(EXE) : zblat3_3m.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME)
$(FC) $(FLDFLAGS) -o $@ zblat3_3m.$(SUFFIX) $(XERBLA_TEST) ../$(LIBNAME) $(EXTRALIB) $(CEXTRALIB)
endif
+1
View File
@@ -2401,6 +2401,7 @@
* .. Common blocks ..
COMMON /INFOC/INFOT, NOUTC, OK, LERR
* .. Executable Statements ..
CALL OPENBLAS_TEST_SET_XERBLA
* OK is set to .FALSE. by the special version of XERBLA or by CHKXER
* if anything is wrong.
OK = .TRUE.
+1
View File
@@ -2019,6 +2019,7 @@
* .. Common blocks ..
COMMON /INFOC/INFOT, NOUTC, OK, LERR
* .. Executable Statements ..
CALL OPENBLAS_TEST_SET_XERBLA
* OK is set to .FALSE. by the special version of XERBLA or by CHKXER
* if anything is wrong.
OK = .TRUE.
+1
View File
@@ -1976,6 +1976,7 @@
* .. Common blocks ..
COMMON /INFOC/INFOT, NOUTC, OK, LERR
* .. Executable Statements ..
CALL OPENBLAS_TEST_SET_XERBLA
* OK is set to .FALSE. by the special version of XERBLA or by CHKXER
* if anything is wrong.
OK = .TRUE.
+1
View File
@@ -2351,6 +2351,7 @@
* .. Common blocks ..
COMMON /INFOC/INFOT, NOUTC, OK, LERR
* .. Executable Statements ..
CALL OPENBLAS_TEST_SET_XERBLA
* OK is set to .FALSE. by the special version of XERBLA or by CHKXER
* if anything is wrong.
OK = .TRUE.
+1
View File
@@ -1873,6 +1873,7 @@
* .. Common blocks ..
COMMON /INFOC/INFOT, NOUTC, OK, LERR
* .. Executable Statements ..
CALL OPENBLAS_TEST_SET_XERBLA
* OK is set to .FALSE. by the special version of XERBLA or by CHKXER
* if anything is wrong.
OK = .TRUE.
+1
View File
@@ -2351,6 +2351,7 @@
* .. Common blocks ..
COMMON /INFOC/INFOT, NOUTC, OK, LERR
* .. Executable Statements ..
CALL OPENBLAS_TEST_SET_XERBLA
* OK is set to .FALSE. by the special version of XERBLA or by CHKXER
* if anything is wrong.
OK = .TRUE.
+1
View File
@@ -1873,6 +1873,7 @@
* .. Common blocks ..
COMMON /INFOC/INFOT, NOUTC, OK, LERR
* .. Executable Statements ..
CALL OPENBLAS_TEST_SET_XERBLA
* OK is set to .FALSE. by the special version of XERBLA or by CHKXER
* if anything is wrong.
OK = .TRUE.
+51
View File
@@ -0,0 +1,51 @@
/***************************************************************************
Copyright (c) 2026, 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 "common.h"
#ifdef OPENBLAS_TEST_USE_XERBLA_HANDLER
static void openblas_test_xerbla(const char *name, const blasint *info,
size_t name_length) {
blasint fortran_length = (blasint)name_length;
blasint fortran_info;
if (name == NULL || info == NULL || fortran_length < 0 ||
(size_t)fortran_length != name_length)
return;
fortran_info = *info;
BLASFUNC(xerbla)((char *)name, &fortran_info, fortran_length);
}
#endif
void BLASFUNC(openblas_test_set_xerbla)(void) {
#ifdef OPENBLAS_TEST_USE_XERBLA_HANDLER
openblas_set_xerbla(openblas_test_xerbla);
#endif
}
+1
View File
@@ -2408,6 +2408,7 @@
* .. Common blocks ..
COMMON /INFOC/INFOT, NOUTC, OK, LERR
* .. Executable Statements ..
CALL OPENBLAS_TEST_SET_XERBLA
* OK is set to .FALSE. by the special version of XERBLA or by CHKXER
* if anything is wrong.
OK = .TRUE.
+1
View File
@@ -2026,6 +2026,7 @@
* .. Common blocks ..
COMMON /INFOC/INFOT, NOUTC, OK, LERR
* .. Executable Statements ..
CALL OPENBLAS_TEST_SET_XERBLA
* OK is set to .FALSE. by the special version of XERBLA or by CHKXER
* if anything is wrong.
OK = .TRUE.
+1
View File
@@ -1979,6 +1979,7 @@
* .. Common blocks ..
COMMON /INFOC/INFOT, NOUTC, OK, LERR
* .. Executable Statements ..
CALL OPENBLAS_TEST_SET_XERBLA
* OK is set to .FALSE. by the special version of XERBLA or by CHKXER
* if anything is wrong.
OK = .TRUE.
+26
View File
@@ -48,3 +48,29 @@ CTEST(dsdot,dsdot_n_1)
}
#endif
#ifdef ARMV8
#if defined(BUILD_SINGLE)
CTEST(sdot,sdot_n_1)
{
static float x[64], y[64];
for (int i = 0; i < 64; i++) { x[i] = 1.0f; y[i] = 1.0f; }
blasint n = 64, inc = 1;
float junk[4] = {1e6f, 1e6f, 1e6f, 1e6f};
__asm__ volatile("ld1 {v0.4s}, [%0]" :: "r"(junk) : "v0");
float r = BLASFUNC(sdot)(&n, x, &inc, y, &inc);
ASSERT_DBL_NEAR_TOL(64.,r, DOUBLE_EPS);
}
#endif
#if defined(BUILD_DOUBLE)
CTEST(ddot,ddot_n_1)
{
static double x[64], y[64];
for (int i = 0; i < 64; i++) { x[i] = 1.0f; y[i] = 1.0f; }
blasint n = 64, inc = 1;
double junk[4] = {1e6f, 1e6f, 1e6f, 1e6f};
__asm__ volatile("ld1 {v0.4s}, [%0]" :: "r"(junk) : "v0");
double r = BLASFUNC(ddot)(&n, x, &inc, y, &inc);
ASSERT_DBL_NEAR_TOL(64.,r, DOUBLE_EPS);
}
#endif
#endif
-1
View File
@@ -45,7 +45,6 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
extern int check_error(void);
extern void set_xerbla(char* current_rout, int expected_info);
extern int BLASFUNC(xerbla)(char *name, blasint *info, blasint length);
extern void srand_generate(float *alpha, blasint n);
extern void drand_generate(double *alpha, blasint n);
+136 -43
View File
@@ -57,21 +57,27 @@ static struct DATA_CGEADD data_cgeadd;
* param beta - scaling factor for matrix C
* param cptr - refer to matrix C
* param ldc - leading dimension of C
* param transa - Traspose of A
* param transc - Transpose of C
*/
static void cgeadd_trusted(blasint m, blasint n, float *alpha, float *aptr,
blasint lda, float *beta, float *cptr, blasint ldc)
blasint lda, float *beta, float *cptr, blasint ldc,
OPENBLAS_CONST enum CBLAS_TRANSPOSE transa,
OPENBLAS_CONST enum CBLAS_TRANSPOSE transc)
{
blasint i;
blasint one=1;
blasint inc_a = (transa == CblasTrans) ? lda : 1;
blasint inc_c = (transc == CblasTrans) ? ldc : 1;
lda *= 2;
ldc *= 2;
blasint step_a = (transa == CblasTrans) ? 1 : lda;
blasint step_c = (transc == CblasTrans) ? 1 : ldc;
for (i = 0; i < n; i++)
{
BLASFUNC(caxpby)(&m, alpha, aptr, &one, beta, cptr, &one);
aptr += lda;
cptr += ldc;
BLASFUNC(caxpby)(&m, alpha, aptr, &inc_a, beta, cptr, &inc_c);
aptr += step_a*2;
cptr += step_c*2;
}
}
@@ -91,6 +97,8 @@ static void cgeadd_trusted(blasint m, blasint n, float *alpha, float *aptr,
* return norm of differences
*/
static float check_cgeadd(char api, OPENBLAS_CONST enum CBLAS_ORDER order,
OPENBLAS_CONST enum CBLAS_TRANSPOSE transa,
OPENBLAS_CONST enum CBLAS_TRANSPOSE transc,
blasint m, blasint n, float *alpha, blasint lda,
float *beta, blasint ldc)
{
@@ -112,14 +120,19 @@ static float check_cgeadd(char api, OPENBLAS_CONST enum CBLAS_ORDER order,
data_cgeadd.c_verify[i] = data_cgeadd.c_test[i];
cgeadd_trusted(cols, rows, alpha, data_cgeadd.a_test, lda,
beta, data_cgeadd.c_verify, ldc);
beta, data_cgeadd.c_verify, ldc,transa, transc);
if (api == 'F')
if (api == 'F'){
char transa_f = (transa == CblasTrans) ? 'T' : 'N';
char transc_f = (transc == CblasTrans) ? 'T' : 'N';
BLASFUNC(cgeadd)(&m, &n, alpha, data_cgeadd.a_test, &lda,
beta, data_cgeadd.c_test, &ldc);
beta, data_cgeadd.c_test, &ldc,&transa_f, &transc_f);
}
#ifndef NO_CBLAS
else
cblas_cgeadd(order, m, n, alpha, data_cgeadd.a_test, lda,
cblas_cgeadd(order,transa,transc, m, n, alpha, data_cgeadd.a_test, lda,
beta, data_cgeadd.c_test, ldc);
#endif
@@ -142,6 +155,8 @@ static float check_cgeadd(char api, OPENBLAS_CONST enum CBLAS_ORDER order,
* return TRUE if everything is ok, otherwise FALSE
*/
static int check_badargs(char api, OPENBLAS_CONST enum CBLAS_ORDER order,
OPENBLAS_CONST enum CBLAS_TRANSPOSE transa,
OPENBLAS_CONST enum CBLAS_TRANSPOSE transc,
blasint m, blasint n, blasint lda,
blasint ldc, int expected_info)
{
@@ -150,12 +165,17 @@ static int check_badargs(char api, OPENBLAS_CONST enum CBLAS_ORDER order,
set_xerbla("CGEADD ", expected_info);
if (api == 'F')
if (api == 'F'){
char transa_f = (transa == CblasTrans) ? 'T' : 'N';
char transc_f = (transc == CblasTrans) ? 'T' : 'N';
BLASFUNC(cgeadd)(&m, &n, alpha, data_cgeadd.a_test, &lda,
beta, data_cgeadd.c_test, &ldc);
beta, data_cgeadd.c_test, &ldc,&transa_f, &transc_f);
}
#ifndef NO_CBLAS
else
cblas_cgeadd(order, m, n, alpha, data_cgeadd.a_test, lda,
cblas_cgeadd(order,transa, transc, m, n, alpha, data_cgeadd.a_test, lda,
beta, data_cgeadd.c_test, ldc);
#endif
@@ -183,7 +203,7 @@ CTEST(cgeadd, matrix_n_100_m_100)
float alpha[] = {3.0f, 2.0f};
float beta[] = {1.0f, 3.0f};
float norm = check_cgeadd('F', order, m, n, alpha, lda, beta, ldc);
float norm = check_cgeadd('F', order,CblasNoTrans, CblasNoTrans,m, n, alpha, lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
}
@@ -210,7 +230,7 @@ CTEST(cgeadd, matrix_n_100_m_100_alpha_zero)
float alpha[] = {0.0f, 0.0f};
float beta[] = {2.5f, 1.0f};
float norm = check_cgeadd('F', order, m, n, alpha, lda, beta, ldc);
float norm = check_cgeadd('F', order,CblasNoTrans, CblasNoTrans, m, n, alpha, lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
}
@@ -237,7 +257,7 @@ CTEST(cgeadd, matrix_n_100_m_100_beta_zero)
float alpha[] = {3.0f, 1.5f};
float beta[] = {0.0f, 0.0f};
float norm = check_cgeadd('F', order, m, n, alpha, lda, beta, ldc);
float norm = check_cgeadd('F', order,CblasNoTrans, CblasNoTrans, m, n, alpha, lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
}
@@ -264,7 +284,7 @@ CTEST(cgeadd, matrix_n_100_m_100_alpha_beta_zero)
float alpha[] = {0.0f, 0.0f};
float beta[] = {0.0f, 0.0f};
float norm = check_cgeadd('F', order, m, n, alpha, lda, beta, ldc);
float norm = check_cgeadd('F', order,CblasNoTrans, CblasNoTrans, m, n, alpha, lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
}
@@ -290,7 +310,7 @@ CTEST(cgeadd, matrix_n_100_m_50)
float alpha[] = {1.0f, 1.0f};
float beta[] = {1.0f, 1.0f};
float norm = check_cgeadd('F', order, m, n, alpha, lda, beta, ldc);
float norm = check_cgeadd('F', order,CblasNoTrans, CblasNoTrans, m, n, alpha, lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
}
@@ -313,7 +333,7 @@ CTEST(cgeadd, xerbla_n_invalid)
int expected_info = 2;
int passed = check_badargs('F', order, m, n, lda, ldc, expected_info);
int passed = check_badargs('F', order,CblasNoTrans, CblasNoTrans, m, n, lda, ldc, expected_info);
ASSERT_EQUAL(TRUE, passed);
}
@@ -335,7 +355,7 @@ CTEST(cgeadd, xerbla_m_invalid)
int expected_info = 1;
int passed = check_badargs('F', order, m, n, lda, ldc, expected_info);
int passed = check_badargs('F', order,CblasNoTrans, CblasNoTrans, m, n, lda, ldc, expected_info);
ASSERT_EQUAL(TRUE, passed);
}
@@ -356,7 +376,7 @@ CTEST(cgeadd, xerbla_lda_invalid)
int expected_info = 5;
int passed = check_badargs('F', order, m, n, lda, ldc, expected_info);
int passed = check_badargs('F', order,CblasNoTrans, CblasNoTrans, m, n, lda, ldc, expected_info);
ASSERT_EQUAL(TRUE, passed);
}
@@ -377,7 +397,7 @@ CTEST(cgeadd, xerbla_ldc_invalid)
int expected_info = 8;
int passed = check_badargs('F', order, m, n, lda, ldc, expected_info);
int passed = check_badargs('F', order,CblasNoTrans, CblasNoTrans, m, n, lda, ldc, expected_info);
ASSERT_EQUAL(TRUE, passed);
}
@@ -398,7 +418,7 @@ CTEST(cgeadd, n_zero)
float alpha[] = {1.0f, 1.0f};
float beta[] = {1.0f, 1.0f};
float norm = check_cgeadd('F', order, m, n, alpha, lda, beta, ldc);
float norm = check_cgeadd('F', order,CblasNoTrans, CblasNoTrans, m, n, alpha, lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
}
@@ -420,7 +440,7 @@ CTEST(cgeadd, m_zero)
float alpha[] = {1.0f, 1.0f};
float beta[] = {1.0f, 1.0f};
float norm = check_cgeadd('F', order, m, n, alpha, lda, beta, ldc);
float norm = check_cgeadd('F', order,CblasNoTrans, CblasNoTrans, m, n, alpha, lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
}
@@ -447,7 +467,7 @@ CTEST(cgeadd, c_api_matrix_n_100_m_100)
float alpha[] = {2.0f, 1.0f};
float beta[] = {1.0f, 3.0f};
float norm = check_cgeadd('C', order, m, n, alpha,
float norm = check_cgeadd('C', order,CblasNoTrans, CblasNoTrans, m, n, alpha,
lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
@@ -475,7 +495,7 @@ CTEST(cgeadd, c_api_matrix_n_100_m_100_row_major)
float alpha[] = {4.0f, 1.5f};
float beta[] = {2.0f, 1.0f};
float norm = check_cgeadd('C', order, m, n, alpha,
float norm = check_cgeadd('C', order,CblasNoTrans, CblasNoTrans, m, n, alpha,
lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
@@ -503,7 +523,7 @@ CTEST(cgeadd, c_api_matrix_n_50_m_100_row_major)
float alpha[] = {3.0f, 2.5f};
float beta[] = {1.0f, 2.0f};
float norm = check_cgeadd('C', order, m, n, alpha,
float norm = check_cgeadd('C', order,CblasNoTrans, CblasNoTrans, m, n, alpha,
lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
@@ -532,7 +552,7 @@ CTEST(cgeadd, c_api_matrix_n_100_m_100_alpha_zero)
float alpha[] = {0.0f, 0.0f};
float beta[] = {1.0f, 1.0f};
float norm = check_cgeadd('C', order, m, n, alpha,
float norm = check_cgeadd('C', order,CblasNoTrans, CblasNoTrans, m, n, alpha,
lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
@@ -561,7 +581,7 @@ CTEST(cgeadd, c_api_matrix_n_100_m_100_beta_zero)
float alpha[] = {3.0f, 1.5f};
float beta[] = {0.0f, 0.0f};
float norm = check_cgeadd('C', order, m, n, alpha,
float norm = check_cgeadd('C', order,CblasNoTrans, CblasNoTrans, m, n, alpha,
lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
@@ -590,7 +610,7 @@ CTEST(cgeadd, c_api_matrix_n_100_m_100_alpha_beta_zero)
float alpha[] = {0.0f, 0.0f};
float beta[] = {0.0f, 0.0f};
float norm = check_cgeadd('C', order, m, n, alpha,
float norm = check_cgeadd('C', order,CblasNoTrans, CblasNoTrans, m, n, alpha,
lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
@@ -617,7 +637,7 @@ CTEST(cgeadd, c_api_matrix_n_100_m_50)
float alpha[] = {2.0f, 3.0f};
float beta[] = {2.0f, 4.0f};
float norm = check_cgeadd('C', order, m, n, alpha,
float norm = check_cgeadd('C', order,CblasNoTrans, CblasNoTrans, m, n, alpha,
lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
@@ -641,7 +661,7 @@ CTEST(cgeadd, c_api_xerbla_invalid_order)
int expected_info = 0;
int passed = check_badargs('C', order, m, n, lda, ldc, expected_info);
int passed = check_badargs('C', order,CblasNoTrans, CblasNoTrans, m, n, lda, ldc, expected_info);
ASSERT_EQUAL(TRUE, passed);
}
@@ -665,7 +685,7 @@ CTEST(cgeadd, c_api_xerbla_n_invalid)
int expected_info = 2;
int passed = check_badargs('C', order, m, n, lda, ldc, expected_info);
int passed = check_badargs('C', order,CblasNoTrans, CblasNoTrans, m, n, lda, ldc, expected_info);
ASSERT_EQUAL(TRUE, passed);
}
@@ -689,7 +709,7 @@ CTEST(cgeadd, c_api_xerbla_n_invalid_row_major)
int expected_info = 2;
int passed = check_badargs('C', order, m, n, lda, ldc, expected_info);
int passed = check_badargs('C', order,CblasNoTrans, CblasNoTrans, m, n, lda, ldc, expected_info);
ASSERT_EQUAL(TRUE, passed);
}
@@ -713,7 +733,7 @@ CTEST(cgeadd, c_api_xerbla_m_invalid)
int expected_info = 1;
int passed = check_badargs('C', order, m, n, lda, ldc, expected_info);
int passed = check_badargs('C', order,CblasNoTrans, CblasNoTrans, m, n, lda, ldc, expected_info);
ASSERT_EQUAL(TRUE, passed);
}
@@ -737,7 +757,7 @@ CTEST(cgeadd, c_api_xerbla_m_invalid_row_major)
int expected_info = 1;
int passed = check_badargs('C', order, m, n, lda, ldc, expected_info);
int passed = check_badargs('C', order,CblasNoTrans, CblasNoTrans, m, n, lda, ldc, expected_info);
ASSERT_EQUAL(TRUE, passed);
}
@@ -760,7 +780,7 @@ CTEST(cgeadd, c_api_xerbla_lda_invalid)
int expected_info = 5;
int passed = check_badargs('C', order, m, n, lda, ldc, expected_info);
int passed = check_badargs('C', order,CblasNoTrans, CblasNoTrans, m, n, lda, ldc, expected_info);
ASSERT_EQUAL(TRUE, passed);
}
@@ -783,7 +803,7 @@ CTEST(cgeadd, c_api_xerbla_lda_invalid_row_major)
int expected_info = 5;
int passed = check_badargs('C', order, m, n, lda, ldc, expected_info);
int passed = check_badargs('C', order,CblasNoTrans, CblasNoTrans, m, n, lda, ldc, expected_info);
ASSERT_EQUAL(TRUE, passed);
}
@@ -806,7 +826,7 @@ CTEST(cgeadd, c_api_xerbla_ldc_invalid)
int expected_info = 8;
int passed = check_badargs('C', order, m, n, lda, ldc, expected_info);
int passed = check_badargs('C', order,CblasNoTrans, CblasNoTrans, m, n, lda, ldc, expected_info);
ASSERT_EQUAL(TRUE, passed);
}
@@ -829,7 +849,7 @@ CTEST(cgeadd, c_api_xerbla_ldc_invalid_row_major)
int expected_info = 8;
int passed = check_badargs('C', order, m, n, lda, ldc, expected_info);
int passed = check_badargs('C', order,CblasNoTrans, CblasNoTrans, m, n, lda, ldc, expected_info);
ASSERT_EQUAL(TRUE, passed);
}
@@ -852,7 +872,7 @@ CTEST(cgeadd, c_api_n_zero)
float alpha[] = {1.0f, 1.0f};
float beta[] = {1.0f, 1.0f};
float norm = check_cgeadd('C', order, m, n, alpha,
float norm = check_cgeadd('C', order,CblasNoTrans, CblasNoTrans, m, n, alpha,
lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
@@ -877,10 +897,83 @@ CTEST(cgeadd, c_api_m_zero)
float alpha[] = {1.0f, 1.0f};
float beta[] = {1.0f, 1.0f};
float norm = check_cgeadd('C', order, m, n, alpha,
float norm = check_cgeadd('C', order,CblasNoTrans, CblasNoTrans, m, n, alpha,
lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
}
CTEST(cgeadd, c_api_matrix_2x2_transA) {
blasint m = 2;
blasint n = 2;
blasint lda = 2;
blasint ldc = 2;
float alpha[] = {1.0f, 0.0f};
float beta[] = {0.0f, 0.0f};
float a_test[8] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f};
float c_test[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
float c_verify[8] = {1.0f, 2.0f, 5.0f, 6.0f, 3.0f, 4.0f, 7.0f, 8.0f};
cblas_cgeadd(CblasColMajor, CblasTrans, CblasNoTrans, m, n, alpha, a_test,
lda, beta, c_test, ldc);
blasint i;
for (i = 0; i < 8; i++) {
ASSERT_DBL_NEAR_TOL(c_verify[i], c_test[i], SINGLE_EPS);
}
}
/**
* Custom C API specific test
* Test BOTH transposed (C^T = A^T) with a simple 2x2 complex float matrix
*/
CTEST(cgeadd, c_api_matrix_2x2_transA_transC) {
blasint m = 2;
blasint n = 2;
blasint lda = 2;
blasint ldc = 2;
float alpha[] = {1.0f, 0.0f};
float beta[] = {0.0f, 0.0f};
float a_test[8] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f};
float c_test[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f};
float c_verify[8] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f};
cblas_cgeadd(CblasColMajor, CblasTrans, CblasTrans, m, n, alpha, a_test, lda,
beta, c_test, ldc);
blasint i;
for (i = 0; i < 8; i++) {
ASSERT_DBL_NEAR_TOL(c_verify[i], c_test[i], SINGLE_EPS);
}
}
/**
* C API specific test - Transposed A (Complex Single Precision)
* Fuzzes your core complex float pointer math against a large 100x100 random matrix.
*/
CTEST(cgeadd, c_api_matrix_n_100_m_100_transA) {
CBLAS_ORDER order = CblasColMajor;
blasint n = N;
blasint m = M;
blasint lda = n;
blasint ldc = m;
float alpha[] = {2.0f, -1.0f};
float beta[] = {1.5f, 3.0f};
float norm = check_cgeadd('C', order, CblasTrans, CblasNoTrans, m, n, alpha,
lda, beta, ldc);
ASSERT_DBL_NEAR_TOL(0.0f, norm, SINGLE_EPS);
}
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More