-
Notifications
You must be signed in to change notification settings - Fork 186
Add solve based on OpenBLAS #710
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -133,6 +133,7 @@ Important options are | |
Compiling with maximum rank 15 can be resource intensive and requires at least 16 GB of memory to allow parallel compilation or 4 GB memory for sequential compilation. | ||
- `-DBUILD_SHARED_LIBS` set to `on` in case you want link your application dynamically against the standard library (default: `off`). | ||
- `-DBUILD_TESTING` set to `off` in case you want to disable the stdlib tests (default: `on`). | ||
- `-DBUILD_OPENBLAS` set to `on` in case you want to use routines based on OpenBLAS (default: `off`). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
- `-DCMAKE_VERBOSE_MAKEFILE` is by default set to `Off`, but if set to `On` will show commands used to compile the code. | ||
- `-DCMAKE_BUILD_TYPE` is by default set to `RelWithDebInfo`, which uses compiler flags suitable for code development (but with only `-O2` optimization). Beware the compiler flags set this way will override any compiler flags specified via `FFLAGS`. To prevent this, use `-DCMAKE_BUILD_TYPE=NoConfig` in conjunction with `FFLAGS`. | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -6,6 +6,17 @@ title: linalg | |||||
|
||||||
[TOC] | ||||||
|
||||||
The stdlib linear algebra functions rely on BLAS and LAPACK to provide | ||||||
efficient low level implementations of standard linear algebra algorithms. | ||||||
|
||||||
If possible, highly optimized libraries that take advantage of specialized processor functionality are preferred. | ||||||
Examples of such libraries are [OpenBLAS][1], [oneAPI MKL(TM)][2]. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
Because these libraries are multithreaded and processor dependent, | ||||||
environment variables may be required to control the number of threads or to specify the processor architecture. | ||||||
|
||||||
[1]: https://www.openblas.net/ | ||||||
[2]: https://www.intel.com/content/www/us/en/developer/tools/oneapi/onemkl.html | ||||||
|
||||||
## `diag` - Create a diagonal array or extract the diagonal elements of an array | ||||||
|
||||||
### Status | ||||||
|
@@ -425,3 +436,43 @@ Specifically, upper Hessenberg matrices satisfy `a_ij = 0` when `j < i-1`, and l | |||||
```fortran | ||||||
{!example/linalg/example_is_hessenberg.f90!} | ||||||
``` | ||||||
|
||||||
## `solve` - Solve a-linear-matrix-equation | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
### Status | ||||||
|
||||||
Experimental | ||||||
|
||||||
### Description | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be good to add somewhere to which BLAS procedure it is linked with |
||||||
|
||||||
Solve a linear matrix equation, or system of linear scalar equations. | ||||||
|
||||||
Note: `solve` supports only single and double precision floating point types. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This "note" will be implicitely mentioned through the description of the arguments. Therefore, it could be removed |
||||||
|
||||||
### Class | ||||||
|
||||||
Impure function. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For such procedures, I would prefera subroutine over a function, especially for efficienct with large vectors/matrices. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Subroutines are usually faster than functions, functions are usually easier to use but may cause performance degradation. If you need high performance, you should use subroutines. If you need simpler code, you should use a function. Intuitively, solving a system of
subroutine solve_(a, b)
real, intent(inout) :: a(:, :), b(:, :)
integer :: ipiv(size(a, 1)), info
call sgesv(size(a, 1), size(b, 2), a, size(a, 1), ipiv, b, size(b, 1), info)
end subroutine solve_
|
||||||
|
||||||
### Synatx | ||||||
|
||||||
`x = [[stdlib_linalg(module):solve(interface)]](a,b)` | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could |
||||||
|
||||||
### Arguments | ||||||
|
||||||
`a`: Shall be a rank-2 array of either `real` or `complex` type. This argument is `intent(in)`. Coefficient matrix. | ||||||
|
||||||
`b`: Shall be a rank-2 array of either `real` or `complex` type. This argument is `intent(in)`. Ordinate or “dependent variable” values. | ||||||
|
||||||
Note: `a` and `b` shall be of the same type. | ||||||
|
||||||
### Return value | ||||||
|
||||||
Returns a rank-2 array. Solution to the system `ax = b`. Returned shape is identical to `b`. | ||||||
|
||||||
### Example | ||||||
|
||||||
Solve the system of equations `x1 + 2 * x2 = 1` and `3 * x1 + 5 * x2 = 2`. | ||||||
|
||||||
```fortran | ||||||
{!example/linalg/example_solve.f90!} | ||||||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
program example_solve | ||
use stdlib_linalg, only: solve | ||
implicit none | ||
real(4) :: a(2, 2), b(2, 1), x(2, 1) | ||
a = reshape([1, 3, 2, 5], [2, 2]) | ||
b = reshape([1, 2], [2, 1]) | ||
x = solve(a, b) | ||
print *, x(:, 1) ! [-1., 1.] | ||
end program example_solve |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#! Define BLAS kinds and types | ||
#:set BLAS_REAL_KINDS = ["sp", "dp"] | ||
#:set BLAS_CMPLX_KINDS = ["sp", "dp"] | ||
|
||
#:set BLAS_REAL_GESV = ["sgesv", "dgesv"] | ||
#:set BLAS_CMPLX_GESV = ["cgesv", "zgesv"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
#:include "common.fypp" | ||
#:include "BLAS_common.fypp" | ||
#:set RCI_KINDS_TYPES = REAL_KINDS_TYPES + CMPLX_KINDS_TYPES + INT_KINDS_TYPES | ||
module stdlib_linalg | ||
!!Provides a support for various linear algebra procedures | ||
|
@@ -24,6 +25,10 @@ module stdlib_linalg | |
public :: is_triangular | ||
public :: is_hessenberg | ||
|
||
#:if defined("USE_OPENBLAS") | ||
public :: solve | ||
#:endif | ||
|
||
interface diag | ||
!! version: experimental | ||
!! | ||
|
@@ -214,6 +219,25 @@ module stdlib_linalg | |
#:endfor | ||
end interface is_hessenberg | ||
|
||
#:if defined("USE_OPENBLAS") | ||
interface solve | ||
!! version: experimental | ||
!! | ||
!! Solve a linear matrix equation, or system of linear scalar equations | ||
!! ([Specification](../page/specs/stdlib_linalg.html# | ||
!! solve-solve-a-linear-matrix-equation)) | ||
#:set REAL_KINDS_TYPES_GESV = list(zip(BLAS_REAL_KINDS, REAL_TYPES, BLAS_REAL_GESV)) | ||
#:set CMPLX_KINDS_TYPES_GESV = list(zip(BLAS_CMPLX_KINDS, CMPLX_TYPES, BLAS_CMPLX_GESV)) | ||
#:set RC_KINDS_TYPES_GESV = REAL_KINDS_TYPES_GESV + CMPLX_KINDS_TYPES_GESV | ||
#:for k1, t1, g1 in RC_KINDS_TYPES_GESV | ||
module function solve_${t1[0]}$${k1}$(a, b) result(x) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would prefer a subroutine-style interface, e.g. subroutine solve(X, A, B) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with the above. It makes more sense to use a subroutine, so that the code stays performant when large matrices are involved. Also, would it make sense to call the procedure something like |
||
${t1}$, intent(in) :: a(:, :), b(:, :) | ||
${t1}$ :: x(size(b, 1), size(b, 2)) | ||
end function solve_${t1[0]}$${k1}$ | ||
#:endfor | ||
end interface solve | ||
#:endif | ||
|
||
contains | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#:include "common.fypp" | ||
#:include "BLAS_common.fypp" | ||
#:set REAL_KINDS_TYPES_GESV = list(zip(BLAS_REAL_KINDS, REAL_TYPES, BLAS_REAL_GESV)) | ||
#:set CMPLX_KINDS_TYPES_GESV = list(zip(BLAS_CMPLX_KINDS, CMPLX_TYPES, BLAS_CMPLX_GESV)) | ||
#:set RC_KINDS_TYPES_GESV = REAL_KINDS_TYPES_GESV + CMPLX_KINDS_TYPES_GESV | ||
submodule (stdlib_linalg) stdlib_linalg_solve | ||
implicit none | ||
contains | ||
#:for k1, t1, g1 in RC_KINDS_TYPES_GESV | ||
module function solve_${t1[0]}$${k1}$(a, b) result(x) | ||
${t1}$, intent(in) :: a(:, :), b(:, :) | ||
${t1}$ :: x(size(b, 1), size(b, 2)) | ||
${t1}$ :: a_local(size(a, 1), size(a, 2)) | ||
integer :: ipiv(size(a, 1)), info | ||
a_local = a | ||
x = b | ||
call ${g1}$(size(a, 1), size(b, 2), a_local, size(a, 1), ipiv, x, size(b, 1), info) | ||
end function solve_${t1[0]}$${k1}$ | ||
#:endfor | ||
end submodule stdlib_linalg_solve |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BUILD_WITH_OPENBLAS
may be better