# Fpm build with BLAS, local and CI

**URL:** <https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397>\
**Category:** Help\
**Created:** [July 27, 2024, 2:34pm UTC](https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397 "2024-07-27T14:34:42Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![HugoMVale](https://avatars.discourse-cdn.com/v4/letter/h/e19adc/32.png) [@HugoMVale](https://fortran-lang.discourse.group/u/HugoMVale)\
**Post date:** [July 27, 2024, 2:34pm UTC](https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397/1 "2024-07-27T14:34:42Z")

</div>

AFAIK, `fpm` has a link option in the toml file to support linking with BLAS and LAPACK.

```toml
[build]
...
link = ["blas"]

```

However, I don’t understand two important things:

- How do I tell `fpm` where BLAS is to be found?
- How can the linking be made to work locally (I have OpenBlas in MSYS2) as well as in the CI, in a transparent manner?

Thanks.

---

<div class="post-metadata">

**Author:** ![urbanjost](https://avatars.discourse-cdn.com/v4/letter/u/0ea827/32.png) [@urbanjost](https://fortran-lang.discourse.group/u/urbanjost)\
**Post date:** [July 27, 2024, 9:36pm UTC](https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397/2 "2024-07-27T21:36:04Z")

</div>

These might help

> [@Compiling simple Fortran program using fpm and local lapack and blas](https://fortran-lang.discourse.group/t/compiling-simple-fortran-program-using-fpm-and-local-lapack-and-blas/4754):
>
> I am using fpm and locally installed Lapack and Blas libraries to test the Ax=b for a simple case (without fpm the example works perfectly): here is the example program main use example1, only: say\_hello ! calling module example1.f90 from src implicit none external :: sgesv real :: amat(2, 2) real :: bvec(2) real :: pivot(2) integer :: rcval ,i, j amat = reshape([2., 3., 2., 2.], [2, 2]) bvec = [3., 6.] print\*, 'Amat: ' do j …

> **[FPM + Lapack on GitHub Actions · fortran-lang/fpm · Discussion #618](https://github.com/fortran-lang/fpm/discussions/618)**
>
> Does anybody have an example of using FPM with a project that requires LAPACK and have it working in GitHub Actions. I've got: \[\[test\]\] link = \["lapack"\] ... and that works fine locally. I guess I ...

---

<div class="post-metadata">

**Author:** ![FedericoPerini](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/federicoperini/32/1750_2.png) [@FedericoPerini](https://fortran-lang.discourse.group/u/FedericoPerini)\
**Post date:** [July 28, 2024, 2:06pm UTC](https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397/3 "2024-07-28T14:06:08Z")

</div>

The [Fortran Standard Library](http://github.com/fortran-lang/stdlib) now ships a full BLAS and LAPACK implementation in generic precision, that you can use either with the original API or with a NumPy-styled high-level API.

External BLAS/LAPACK libraries are supported via a cpp macro. For example, you can define:

```toml
[dependencies]
stdlib = { git="https://github.com/fortran-lang/stdlib", branch="stdlib-fpm", preprocess.cpp.macros= ["STDLIB_EXTERNAL_BLAS", "STDLIB_EXTERNAL_LAPACK"] }

```

In this case, both the original API and the high-level API will use the external library. On macOS, that would be running with `--flag '-framework Accelerate'`.

The `link` approach you’re suggesting also works, provided that such libraries can be found by the linker in one of the `LD_LIBRARY_PATH` paths.

---

<div class="post-metadata">

**Author:** ![HugoMVale](https://avatars.discourse-cdn.com/v4/letter/h/e19adc/32.png) [@HugoMVale](https://fortran-lang.discourse.group/u/HugoMVale)\
**Post date:** [July 28, 2024, 4:37pm UTC](https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397/4 "2024-07-28T16:37:30Z")

</div>

Thank you both. I was able solve the issue.

Essentially, my problem was that I didn’t understand the practical result of adding `link = ["mylib"]` to the toml file. In the meantime, I realized that there is no magic: it “just” adds the flag `-lmylib` (for gcc). So, in my case, I just had to change to 🤦‍♂️:

```toml
[build]
...
link = ["openblas"]

```

This works just fine in Windows+MSYS2. To make it work in the CI/CD, I just had to add 2 command lines to install OpenBLAS.

```yml
...
 jobs:
  linux-gcc-build:
      - name: Install GFortran, OpenBLAS
        if: contains(matrix.os, 'ubuntu')
        run: |
          sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_V} 100 \
          --slave /usr/bin/gfortran gfortran /usr/bin/gfortran-${GCC_V} \
          --slave /usr/bin/gcov gcov /usr/bin/gcov-${GCC_V}
          sudo apt-get install libopenblas-dev # <<<<<<

...      
  msys2-gcc-build:
      
      - name: Install MSYS2, GFortran, fpm, OpenBLAS
        uses: msys2/setup-msys2@v2
        with:
          msystem: MINGW64
          update: true
          path-type: inherit
          install: |
            mingw-w64-x86_64-gcc-fortran
            mingw-w64-x86_64-fpm
            mingw-w64-x86_64-openblas # <<<<<<

```

---

<div class="post-metadata">

**Author:** ![HugoMVale](https://avatars.discourse-cdn.com/v4/letter/h/e19adc/32.png) [@HugoMVale](https://fortran-lang.discourse.group/u/HugoMVale)\
**Post date:** [July 28, 2024, 4:54pm UTC](https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397/5 "2024-07-28T16:54:06Z")

</div>

I just had a look. It’s amazing work. Yet another good reason to use stdlib.

How did you guys do that? Did you parse the reference BLAS and LAPACK from netlib, converted that to fyyp and… and … and…?

---

<div class="post-metadata">

**Author:** ![FedericoPerini](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/federicoperini/32/1750_2.png) [@FedericoPerini](https://fortran-lang.discourse.group/u/FedericoPerini)\
**Post date:** [July 28, 2024, 5:04pm UTC](https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397/6 "2024-07-28T17:04:11Z")

</div>

The Netlib version is great in that the code is very well structured (although old). For example, if you have an external function, it will be in a block preceded by an “external functions” comment line, etc.

So I did it with a custom Python script with a combination of code modernization, information gathering from the documentation, plus some final hand made finishes. You can check the script out at the wip repository here:

> <https://github.com/perazz/fortran-lapack/blob/main/scripts/modularize_blas.py>

---

<div class="post-metadata">

**Author:** ![themos](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/themos/32/521_2.png) [@themos](https://fortran-lang.discourse.group/u/themos)\
**Post date:** [July 29, 2024, 9:47am UTC](https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397/7 "2024-07-29T09:47:48Z")

</div>

> [@FedericoPerini](#):
>
> For example, if you have an external function, it will be in a block preceded by an “external functions” comment line, etc.

While employed at NAG, this was known as “NAG style”, and there were scripts that would convert any FORTRAN 77 subprogram source to that style. LRZ still holds on to documentation for those tools [nag\_decs - NAGWare Fortran Tools - f77 Tools](https://www.lrz.de/services/software/programmierung/toolpack/nag_decs.html)

---

<div class="post-metadata">

**Author:** ![mcditoos](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mcditoos/32/5038_2.png) [@mcditoos](https://fortran-lang.discourse.group/u/mcditoos)\
**Post date:** [July 30, 2024, 5:08am UTC](https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397/8 "2024-07-30T05:08:06Z")

</div>

Hi Federico, I’m new to fortran and tried this a few days ago, worked like a charm if the use statements where done from app in the fpm project, but I’m still tryoing to make them work in src. perhaps you know what needs to be done

---

<div class="post-metadata">

**Author:** ![FedericoPerini](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/federicoperini/32/1750_2.png) [@FedericoPerini](https://fortran-lang.discourse.group/u/FedericoPerini)\
**Post date:** [July 30, 2024, 9:33pm UTC](https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397/9 "2024-07-30T21:33:23Z")

</div>

Hi @mcditoos, sorry I’ve just left for vacation. If you can show your issue with an example, I can take a look when I’m back thanks!

---

<div class="post-metadata">

**Author:** ![mcditoos](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/mcditoos/32/5038_2.png) [@mcditoos](https://fortran-lang.discourse.group/u/mcditoos)\
**Post date:** [July 31, 2024, 2:34am UTC](https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397/10 "2024-07-31T02:34:44Z")

</div>

No worries, thanks for replying on your vacation, Enjoy it ! On another note. is there any plans to include matrix exponentials/ square roots and related functions in stdlib\_linear algebra?

---

<div class="post-metadata">

**Author:** ![Bhanu](https://avatars.discourse-cdn.com/v4/letter/b/eb9ed0/32.png) [@Bhanu](https://fortran-lang.discourse.group/u/Bhanu)\
**Post date:** [December 10, 2024, 4:28pm UTC](https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397/11 "2024-12-10T16:28:10Z")

</div>

As you mentioned all functions of LAPACK and BLAS are available. Can you please point how I can I use dgeev? When I am using its shows an error that

Error: Procedure ‘dgeev’ called with an implicit interface at (1) [-Werror=implicit-interface]  
compilation terminated due to -fmax-errors=1.  
 Compilation failed for object " app\_main.f90.o "  
 stopping due to failed compilation  
STOP 1

Thank you for your help.

---

<div class="post-metadata">

**Author:** ![FedericoPerini](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/federicoperini/32/1750_2.png) [@FedericoPerini](https://fortran-lang.discourse.group/u/FedericoPerini)\
**Post date:** [December 10, 2024, 4:36pm UTC](https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397/12 "2024-12-10T16:36:21Z")

</div>

@Bhanu you can find several examples [in the stdlib `examples` folder](https://github.com/fortran-lang/stdlib/tree/master/example/linalg).

Is what you want really to fine-tune `geev`, or do you just seek the eigenvalues to a general matrix? Because if so, I suggest you to use the high-level API for eigenvalues: `eig` and `eigvals`:

- [sample eigendecomposition using stdlib `eig`](https://godbolt.org/z/GejKezz5E)
- [sample eigenvalues using stdlib `eigvals`](https://godbolt.org/z/ehGhYvfja)

If you have a real symmetric or complex Hermitian matrix, you may want to use `eigh` and `eigvalsh`. The full help is [here](https://stdlib.fortran-lang.org/page/specs/stdlib_linalg.html#eig-eigenvalues-and-eigenvectors-of-a-square-matrix).

PS as you mentioned elsewhere, if you build your project with `fpm` please ensure to have `stdlib` as a dependency.

---

<div class="post-metadata">

**Author:** ![Bhanu](https://avatars.discourse-cdn.com/v4/letter/b/eb9ed0/32.png) [@Bhanu](https://fortran-lang.discourse.group/u/Bhanu)\
**Post date:** [December 10, 2024, 4:48pm UTC](https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397/13 "2024-12-10T16:48:25Z")

</div>

Thank you for your reply however, I wanted to solve a generalized eigenvalue problem (also known as the generalized eigenpair problem), which involves finding eigenvalues and eigenvectors for a pair of matrices A and B, such that:

A⋅x=λ⋅B⋅x

Where A and B are square matrices, λ are the eigenvalues, and x are the corresponding eigenvectors (in general dgeev is used for this purpose).

---

<div class="post-metadata">

**Author:** ![FedericoPerini](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/federicoperini/32/1750_2.png) [@FedericoPerini](https://fortran-lang.discourse.group/u/FedericoPerini)\
**Post date:** [December 10, 2024, 5:10pm UTC](https://fortran-lang.discourse.group/t/fpm-build-with-blas-local-and-ci/8397/14 "2024-12-10T17:10:06Z")

</div>

We don’t have a high-level API for that yet (only SciPy has it afaict), but it’s not a problem as you can just use the generalized LAPACK interface, [see this example](https://godbolt.org/z/j9P9ovoxc):

```Fortran
program example_dggev
  use iso_fortran_env, only: dp => real64
  use stdlib_linalg_lapack, only: ggev ! generic-type wrapper to *GGEV functions
  implicit none
  real(dp), allocatable :: A(:,:), B(:,:), ALPHAR(:), ALPHAI(:), BETA(:), VL(:,:), VR(:,:), WORK(:)
  integer :: N, LDA, LDB, LDVL, LDVR, INFO, LWORK, i

  ! Define matrix sizes
  N = 2

  ! Allocate matrices and vectors
  allocate(A(N, N), B(N, N), ALPHAR(N), ALPHAI(N), BETA(N), VL(N, N), VR(N, N))

  ! Define matrices A and B
  A = reshape([1.0_dp, 2.0_dp, 3.0_dp, 4.0_dp], shape=[N, N]) ! Example matrix A
  B = reshape([2.0_dp, 0.0_dp, 0.0_dp, 2.0_dp], shape=[N, N]) ! Example matrix B

  ! Leading dimensions
  LDA = N
  LDB = N
  LDVL = N
  LDVR = N

  ! Query workspace (LWORK)
  LWORK = -1
  allocate(WORK(1))
  call ggev('N', 'V', N, A, LDA, B, LDB, ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, WORK, LWORK, INFO)
  LWORK = nint(WORK(1))
  deallocate(WORK); allocate(WORK(LWORK))
  print *, 'LWORK = ',LWORK
  
  ! Solve the generalized eigenvalue problem A*x = λ*B*x
  call ggev('N', 'V', N, A, LDA, B, LDB, ALPHAR, ALPHAI, BETA, VL, LDVL, VR, LDVR, WORK, LWORK, INFO)

  ! Check for success
  if (INFO == 0) then
    print *, "Generalized eigenvalues (lam = ALPHAR/BETA):"
    print *, (ALPHAR(i)/BETA(i), ALPHAI(i)/BETA(i), i=1, N)
    print *, "Right eigenvectors (VR):"
    print *, VR
  else
    print *, "Error: ggev failed with INFO =", INFO
  end if

  ! Deallocate arrays
  deallocate(A, B, ALPHAR, ALPHAI, BETA, VL, VR)
end program example_dggev

```

Note the correct LAPACK function is `GGEV`, not the simpler `GEEV`.

Please open an Issue on the stdlib page and I’m happy to help add handling of the non-identity eigenvector case!
