Skip to content

Replace C++ code of SSIDS with Fortran - #542

Merged
nimgould merged 11 commits into
masterfrom
spike-ssids-cholesky-fortran
Aug 10, 2026
Merged

Replace C++ code of SSIDS with Fortran#542
nimgould merged 11 commits into
masterfrom
spike-ssids-cholesky-fortran

Conversation

@amontoison

Copy link
Copy Markdown
Collaborator

Remove all the C++ and GPU related code of SSIDS.
I started that a long time ago...
It also removes the need of hwloc.

@amontoison
amontoison requested a review from nimgould August 3, 2026 20:37
@amontoison amontoison self-assigned this Aug 3, 2026
@amontoison amontoison added the enhancement New feature or request label Aug 3, 2026
@codecov-commenter

codecov-commenter commented Aug 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 72.35142% with 107 lines in your changes missing coverage. Please review.
✅ Project coverage is 27.44%. Comparing base (95ca228) to head (aafee4e).

Files with missing lines Patch % Lines
src/slblt/slblt_factort.F90 85.61% 8 Missing and 33 partials ⚠️
src/slblt/C/slblt_ciface.F90 40.67% 29 Missing and 6 partials ⚠️
src/slblt/contrib_iface.F90 0.00% 23 Missing ⚠️
src/slblt/C/slbltt.c 60.00% 3 Missing and 1 partial ⚠️
src/slblt/C/slblttf.c 60.00% 3 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #542      +/-   ##
==========================================
+ Coverage   26.93%   27.44%   +0.51%     
==========================================
  Files         164      152      -12     
  Lines       29197    28151    -1046     
  Branches     8800     8419     -381     
==========================================
- Hits         7863     7725     -138     
+ Misses      18762    17958     -804     
+ Partials     2572     2468     -104     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@amontoison
amontoison force-pushed the spike-ssids-cholesky-fortran branch from d5304b8 to bc05027 Compare August 4, 2026 05:46
@amontoison
amontoison requested a review from jfowkes August 4, 2026 06:43
@nimgould

nimgould commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Thanks, Alexis, that is really great. I will have a look as soon as I can ... I have managed to get a short-term temporary licence for the NAG library, and need to give this (the interface from the new QP solver to NAG) priority before the licence expires next week. I see that you also updated the makemaster file ... thank you!!

I do actually wonder if we should rename the package so as not to confuse the world, particularly as Hussam is planning for the official ssids to evolve. And I need to write docs, and a Python interface.

Do you use AI to help you here?

@jfowkes

jfowkes commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Fantastic thanks @amontoison! We should also incorporate Hussam's adaptive front size fix in ralna/spral#271 as this results in a major performance improvement.

Agreed we should probably change the name as the codebase has diverged so much at this point, unless @haldaas is interested in merging this upstream.

@nimgould

nimgould commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Sorry to be an idiot, as usual

I did a git checkout -b spike-ssids-cholesky-fortran

which seems to have set things here,

git branch --show-current
spike-ssids-cholesky-fortran

but when I tried a git pull, I get

here is no tracking information for the current branch.
Please specify which branch you want to rebase against.
See git-pull(1) for details.

git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

git branch --set-upstream-to=origin/<branch> spike-ssids-cholesky-fortran

Should I follow this advice?

@jfowkes

jfowkes commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Assuming that you did the checkout from the master branch that should work, as you created a new local branch off of the branch you were on previously.

More standard practice is to do a git fetch to get the names of any new remote branches and then a git checkout branchname.

@nimgould

nimgould commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

On the makefile build under gfortran I see:

Warning: Unused variable ‘adc’ ssids_factor.F90:720:35:
Warning: Unused variable ‘adr’ ssids_factor.F90:725:29:
Warning: Unused variable ‘adum’ ssids_factor.F90:719:35:
Warning: Unused variable ‘blk’
Warning: Unused variable ‘ii’ ssids_factor.F90:726:43:
Warning: Unused variable ‘jj’ ssids_factor.F90:719:75:
Warning: Unused variable ‘k’ ssids_factor.F90:719:66:
Warning: Unused variable ‘nr’ ssids_factor.F90:729:60:
Warning: Unused variable ‘tbp’ ssids_factor.F90:730:24:
Warning: Unused variable ‘td11’ ssids_factor.F90:730:30:
Warning: Unused variable ‘td21’ ssids_factor.F90:729:35:
Warning: Unused variable ‘tdoff’ ssids_factor.F90:731:23:
Warning: Unused variable ‘tfin’ ssids_factor.F90:729:55:
Warning: Unused variable ‘tk’ ssids_factor.F90:732:39:
Warning: Unused variable ‘tldw’ ssids_factor.F90:729:51:
Warning: Unused variable ‘tlflag’ ssids_factor.F90:726:70:
Warning: Unused variable ‘tmpi’ ssids_factor.F90:729:23:
Warning: Unused variable ‘tnc’ ssids_factor.F90:729:43:
Warning: Unused variable ‘tnelim’ ssids_factor.F90:729:65:
Warning: Unused variable ‘tnp’ ssids_factor.F90:729:28:
Warning: Unused variable ‘tnr’ ssids_factor.F90:729:28:

nothing serious of course. But when I run the test program
ssidst.F90, I get

Exhaustive test of subroutine interface to ssids
At line 330 of file ssids_factor.F90
Fortran runtime error: Index '6' of dimension 1 of array 'a' above upper bound of 5

Error termination. Backtrace:
#0 0x13185e623e59 in ???
#1 0x13185e624a71 in ???
#2 0x13185e625082 in ???
#3 0x626c1e5975f7 in __galahad_ssids_factor_double_MOD_ldlt_tpp_factor
at /home/nimg/Dropbox/fortran/optrove/galahad/objects/pc64.lnx.gfo/double/ssids_factor.F90:330
#4 0x626c1e59bd7c in __galahad_ssids_factor_double_MOD_run_pivoted._omp_fn.0
at /home/nimg/Dropbox/fortran/optrove/galahad/objects/pc64.lnx.gfo/double/ssids_factor.F90:923
#5 0x13185e3e65bb in ???
#6 0x626c1e58f3f5 in run_pivoted
at /home/nimg/Dropbox/fortran/optrove/galahad/objects/pc64.lnx.gfo/double/ssids_factor.F90:898
#7 0x626c1e597fb9 in __galahad_ssids_factor_double_MOD_ldlt_app_factor
at /home/nimg/Dropbox/fortran/optrove/galahad/objects/pc64.lnx.gfo/double/ssids_factor.F90:787
#8 0x626c1e59bb2e in __galahad_ssids_factor_double_MOD_run_pivoted._omp_fn.0
at /home/nimg/Dropbox/fortran/optrove/galahad/objects/pc64.lnx.gfo/double/ssids_factor.F90:911
#9 0x13185e3e40d2 in ???
#10 0x13185e3ed937 in ???
#11 0x626c1e58d674 in __galahad_ssids_factor_double_MOD_factor_subtree_delay._omp_fn.0
at /home/nimg/Dropbox/fortran/optrove/galahad/objects/pc64.lnx.gfo/double/ssids_factor.F90:2143
#12 0x13185e3ea6fd in ???
#13 0x13185e09cb83 in start_thread
at ./nptl/pthread_create.c:447
#14 0x13185e129d6b in clone3
at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
#15 0xffffffffffffffff in ???
ssids double precision tests

in a call to GEMM. Superficially, it looks like this is trying to access a(m+1,*) of an a(m,n) matrix. So either the argument a(nelim+2, nelim+1) is wrong or the dimensions m-nelim-1, n-nelim-1 are? (perhaps a 0-based mistake)?

Looking at the original C++, I think it should be a(nelim+1,nelin+1), but that could be wrong ... those pesky 0-based flattened index arrays strike again!! I wonder, going forward, if we shouldn't try to make everything here 1-based? It is not very natural in fortran to have nelim going from 0 to n-1 ...

My only other comment here is that it would be nice to put back the C comments (albeit as fortran ones) as these do help explain what the code is trying to do. No hurry on this

@nimgould

nimgould commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

With the NAG compiler, I get

Compiling types Error: types.F90, line 400: No data-edit descriptor for effective item
Error: types.F90, line 401: No data-edit descriptor for effective item
Error: types.F90, line 402: No data-edit descriptor for effective item
Error: types.F90, line 403: No data-edit descriptor for effective item
Error: types.F90, line 404: No data-edit descriptor for effective item
Error: types.F90, line 405: No data-edit descriptor for effective item
Error: types.F90, line 431: No data-edit descriptor for effective item
Error: types.F90, line 433: No data-edit descriptor for effective item
Error: types.F90, line 446: No data-edit descriptor for effective item
Error: types.F90, line 448: No data-edit descriptor for effective item
which seems to suggest that NAG doesn't like the CLASS( SSIDS_control_type ), INTENT( IN ) :: this

@jfowkes

jfowkes commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Aren't "No data-edit descriptor for effective item" errors to do with incorrect format descriptors in write statements? Should hopefully be an easy fix.

@nimgould

nimgould commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Yes, indeed, the error is the 200 FORMAT( '( A, I15 )' )
which should, of course, be 200 FORMAT( A, I15 ) (no quotes)

@nimgould

nimgould commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Same in the following subroutine

200 FORMAT( //, 3A, I2, A )
210 FORMAT( // A, 5( / A ,I12 ), 5( / A, ES12.4 ) )

OK, fixed those, and removed the VOLATILE from
TYPE( contrib_type ), POINTER, VOLATILE :: fcontrib
in contrib_iface.F90 (as AI says that it isn't necessary), the code now compiles under nagfor (a first!!), but then falls over at exactly the same place as for gfortran (above). I'll see what I can do ...

@nimgould

nimgould commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Needless to say, nothing worked with ifx, when compiling ssids.F90 I get an error #5633: Internal compiler error: segmentation violation signal raised Please report this error along with the circumstances in which it occurred in a Software Problem Report. Note: File and line given may not be explicit cause of this error.
compilation aborted for ssids.F90 (code 3)

with no clues to why it failed (deep in the libc stuff). But this is for oneapi/compiler/2024.2, I haven't got a more modern one, I'll see if I can get one ...

OK, it compiles fine under 2026.1, but the test fails with the uninformative symbol lookup error: ../ssids/run_ssids: undefined symbol: __kmpc_alloc, version VERSION

@nimgould

nimgould commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Finally, it compiles and runs with nvfortran

@amontoison

Copy link
Copy Markdown
Collaborator Author

OK, it compiles fine under 2026.1, but the test fails with the uninformative symbol lookup error: ../ssids/run_ssids: undefined symbol: __kmpc_alloc, version VERSION

You need to link with the OpenMP library of Intel: libiomp5.so.
it is why you have undefined symbols.
Don't hesitate to push directly on this branch if you fix something.
I can't work on it before this weekend.

@nimgould

nimgould commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

I tried linking against /opt/intel/oneapi/compiler/latest/lib/libiomp5.so
but nothing changed. I have compiled and linked with -fopenmp, I presume that is ok?

Update: it was my fault, flang also has a libiomp5.so, and was further up my link chain. Changing the order sorted things out.

@jfowkes

jfowkes commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

I believe that to link against Intel OpenMP you need to use -fiopenmp

@nimgould

nimgould commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

I haven't tried that, but I will ... that seems to work too. I still get the very annoying "OMP: Info #269: OMP_NESTED variable deprecated, please use OMP_MAX_ACTIVE_LEVELS instead" message, even though I have set OMP_MAX_ACTIVE_LEVELS ... but it seems that I actively have to remove OMP_NESTED to get rid of the message, doh!

@nimgould

nimgould commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

OK, I'm making progress.

As I suspected, the call to gemm in ldlt_tpp_factor has an incorrect leading array index for both arguments a(.,), these
should be (I believe) nelim+1 not nelim+2. This allows gfortran to run to completion. But, fortunately, nagfor is a stricter compiler, and objects that the second "a" argument a(nelim+1, nelim+2) lies outside the array bounds. gemm will not complain as the m, n argumemts are 0, and gemm will no-op for this. To avoid this,
simply adding a IF ( nelim < n - 1 ) & before the CALL DGEMM does the job.

The next issue is that ldlt_app_solve_diag fails for an edge case;
there is an

IF (i+1 == n .OR. IEEE_IS_FINITE(d(2*i+3))) THEN ...

the first clause is true, but fortran doesn't say in which order clauses should be checked, and the index for d in the 2nd is outside bounds. So a
is1x1 = ( i+1 == fn%nelim )
IF ( .NOT. is1x1 ) is1x1 = ieee_is_finite_local( fn%d( 2*i+3 ) )
solves the issue (I then saw that you did something almost identical in SUBROUTINE alter in numerical_subtree.F90 ;)

But I am now stuck on the alter test. In SUBROUTINE alter (the one in ssids.F90 not numerical_subtree.F90 ) calls subtree%alter() with a segment of the 2-D array that stores the B block (dimension 1 is for the diagonal and dimension 2 for the off diagonal). There is a single part to this array (akeep%nparts = 1), but the
d( 1 : 2, akeep%part( part ) : akeep%part( part + 1 ) - 1 )
gives a d(1:2,1:1) array. It should be d(1:2,1:5). I don't know why
this is the case, I don't know where akeep%part is set. In any event, it causes an out-of-range exception in subtree%alter() as the array is the wrong shape.

Anyway, I'll check all I have so far in, but will be off line for three days ... we have visitors AND my home ethernet is boosting from 32Mbps to 900, as total fibre has finally arrived in the village ... and I very much suspect that my internet provider will mess it up!

@nimgould

nimgould commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

I have pushed an update that I believe fixes the nagfor issue. This is in subroutine alter in ssids, in the call to subtree%alter. I think that this should be
CALL subtree%alter( d( 1, akeep%part( part ) ) )
not
CALL subtree%alter( d( 1 : 2, akeep%part( part ) : akeep%part( part + 1 ) - 1 ) )
as the latter tries to pass a 2x1 vector, while I suspect we should instead be passing a pointer to the first entry in a 2xn matrix (I think that is what the origial C++ code is doing). In any event, the simple ssids test now passes with all my compilers with the makefile install.

Given this, I am happy if you merge, but perhaps we should change ssids -> slblt everywhere first?

@nimgould

nimgould commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

If we are to take control of this package, really we should improve the test example as it is very primitive at the moment

@amontoison

amontoison commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator Author

I believe that to link against Intel OpenMP you need to use -fiopenmp

@nimgould @jfowkes
https://github.com/ralna/GALAHAD/blob/master/meson.build#L165-L176

-fopenmp should also work for ifort / ifx but the documented flag is -qopenmp on linux / mac and /Qopenmp on windows.

@amontoison

amontoison commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator Author

@nimgould I am working on the renaming ssids -> slblt everywhere.
I agree to update the test / example but let's merge this PR before such that it is easier to review.

Update: Nick can you do a final checking and merge the PR (squash + merge) please ?

@amontoison
amontoison force-pushed the spike-ssids-cholesky-fortran branch from c52f632 to fa8984a Compare August 8, 2026 21:59
@nimgould

Copy link
Copy Markdown
Contributor

Agreed. Tests for slblt pass here

@nimgould
nimgould merged commit 6ccd8e5 into master Aug 10, 2026
29 of 30 checks passed
@amontoison
amontoison deleted the spike-ssids-cholesky-fortran branch August 10, 2026 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants