Skip to content

SciPy v1.14.0#5012

Merged
agriyakhetarpal merged 32 commits intopyodide:mainfrom
agriyakhetarpal:feat/package/scipy-1.14.0
Aug 23, 2024
Merged

SciPy v1.14.0#5012
agriyakhetarpal merged 32 commits intopyodide:mainfrom
agriyakhetarpal:feat/package/scipy-1.14.0

Conversation

@agriyakhetarpal
Copy link
Member

@agriyakhetarpal agriyakhetarpal commented Aug 16, 2024

Description

This PR updates SciPy to version 1.14.0. Tagging recipe maintainers: @lesteve, @steppi; and @rgommers, for visibility. SciPy was previously updated in #5011 to version 1.13.1.

Checklists

@agriyakhetarpal
Copy link
Member Author

agriyakhetarpal commented Aug 16, 2024

../scipy/meson.build:147:7: ERROR: Program 'f2py' not found or not executable

I initially thought that there's now a hard requirement for NumPy v2 with SciPy v1.14.0, but that doesn't seem to be the case. I might need to provide hints to Meson/meson-python on where to find it (i.e., in NumPy's directories or in the site-packages directory).

Note to self: I need to go through the changes in scipy/scipy@3c37112 and scipy/scipy@d85ba6b.

@rgommers
Copy link
Contributor

You can build SciPy 1.14 against NumPy 1.26 just fine - only need to remember to then rebuild SciPy when NumPy 2.0 lands.

@rgommers
Copy link
Contributor

If f2py is going missing, the entrypoint may not be installed? It's defined in NumPy's pyproject.toml

@agriyakhetarpal
Copy link
Member Author

Yes. I realise that the error is because while NumPy is indeed built beforehand, it isn't installed into the environment, and therefore the f2py entry point does not exist in PATH. I'm not sure if there's a clean way of having NumPy installed rather than built when building SciPy, so we will have to work around this somehow.

@agriyakhetarpal
Copy link
Member Author

agriyakhetarpal commented Aug 16, 2024

Okay, managed to fix this – I have had to revert all the uses of the f2py generator calls I could find, which were from your commit I mentioned above, @rgommers; it isn't an ideal solution since it conflicts with other patches and the diff is quite big (in terms of both tidiness and upstream-ability – or rather, the lack of them). Although, my hunch is that we don't need to do this at all, though, and simply restoring the sys.executable -m prefix before invoking numpy.f2py should fix it.

Edit: it does, in fact – Meson generators are pretty neat! :)

We are now able to start compiling SciPy v1.14.0. However, it fails with the following logs (truncated here):

Tap to view logs
Program _generate_pyx.py found: YES (/tmp/build-env-vb6iw_yf/bin/python /src/packages/scipy/build/scipy-1.14.0/scipy/linalg/_generate_pyx.py)                                
Program ../_build_utils/echo.py found: YES (/tmp/build-env-vb6iw_yf/bin/python /src/packages/scipy/build/scipy-1.14.0/scipy/linalg/../_build_utils/echo.py)                  
Program ../_generate_sparsetools.py found: YES (/tmp/build-env-vb6iw_yf/bin/python                                                                                           
/src/packages/scipy/build/scipy-1.14.0/scipy/sparse/sparsetools/../_generate_sparsetools.py)                                                                                 
Checking for size of "void*" : 4                                                                                                                                             
Compiler for Fortran supports arguments -w: YES                                                                                                                              
Build targets in project: 197                                                                                                                                                
                                                                                                                                                                             
scipy 1.14.0                                                                                                                                                                 
                                                                                                                                                                             
  User defined options                                                                                                                                                       
    Cross files : /usr/local/lib/python3.12/site-packages/pyodide_build/tools/emscripten.meson.cross                                                                         
    Native files: /src/packages/scipy/build/scipy-1.14.0/build/meson-python-native-file.ini                                                                                  
    buildtype   : release                                                                                                                                                    
    b_ndebug    : if-release                                                                                                                                                 
    b_vscrt     : md                                                                                                                                                         
                                                                                                                                                                             
Found ninja-1.11.1 at /usr/bin/ninja                                                                                                                                         
                                                                                                                                                                             
ERROR: ld.wasm does not support shared libraries.                                                                                                                            
                                                                                                                                                                             
A full log can be found at /src/packages/scipy/build/scipy-1.14.0/build/meson-logs/meson-log.txt                                                                             
                                                                                                                                                                             
ERROR Backend subprocess exited when trying to invoke build_wheel                                                                                                            
[2024-08-16 18:03:21] Failed building package scipy in 34.0 seconds.                                                                                                         
                                                                                                                                                                             
                                                                                                                                                                             
ERROR: cancelling buildall due to error building scipy

It suggests we are compiling a shared library somewhere, but I don't see anything in the log file; it's the same as the above trace. I'm now going to try to find out where a shared library has been defined in the target definitions (and where that changed between v1.13.0 and v1.14.0). I'm also going to try passing additional arguments to the meson setup and meson install commands to see if they can produce step-by-step output or bump the verbosity.

@lucascolley
Copy link

@agriyakhetarpal perhaps scipy/scipy#20321?

@agriyakhetarpal
Copy link
Member Author

Thank you, @lucascolley – will take a look!

@agriyakhetarpal
Copy link
Member Author

Never mind, patch 15 doesn't seem to work, based on the error raised in CI – I think we'll have to remove the f2py generators entirely unless I'm missing any other ways to fix this. I think I had an f2py executable installed in src/.docker_home/local/bin, which led me to believe that it did work like we wanted it to. @lucascolley, I've had a look at scipy/scipy#20321 and I feel that the functionality might not be worth fixing too much for Pyodide – we could either let that be a static_library, or remove the extension module altogether, what do you think?

Also, I now have an issue locally: the build procedure is trying to compile test_fortran.pyf despite the fact that I've disabled the compilation of test modules using install tags (i.e., install-args=--tags=runtime,python-runtime,devel). I don't see why that should happen?

Tap to view logs
730/1344] Compiling Fortran object scipy/io/_test_fortran.cpython-312-wasm32-emscripten.so.p/_test_fortran.f.o                                                              
FAILED: scipy/io/_test_fortran.cpython-312-wasm32-emscripten.so.p/_test_fortran.f.o                                                                                          
/tmp/tmpve9euhz9/gfortran -Iscipy/io/_test_fortran.cpython-312-wasm32-emscripten.so.p -Iscipy/io -I../scipy/io                                                               
-I../../../../../../tmp/build-env-l4q58zjw/lib/python3.12/site-packages/numpy/core/include                                                                                   
-I../../../../../../tmp/build-env-l4q58zjw/lib/python3.12/site-packages/numpy/f2py/src -Iscipy/lib_fortranobject.a.p -Iscipy/libdummy_g77_abi_wrappers.a.p                   
-I/src/packages/.libs/include -I/src/cpython/installs/python-3.12.1/include/python3.12 -I/usr/local/include/python3.12 -fvisibility=hidden -fdiagnostics-color=always        
-DNDEBUG -D_FILE_OFFSET_BITS=64 -Wall -std=legacy -O3 -Wno-conversion -fPIC -Wno-argument-mismatch -Wno-conversion -Wno-maybe-uninitialized -Wno-unused-dummy-argument       
-Wno-unused-label -Wno-unused-variable -Wno-tabs -Jscipy/io/_test_fortran.cpython-312-wasm32-emscripten.so.p -o                                                              
scipy/io/_test_fortran.cpython-312-wasm32-emscripten.so.p/_test_fortran.f.o -c ../scipy/io/_test_fortran.f                                                                   
   read_unformatted_double:                                                                                                                                                  
Error on line 3: syntax error                                                                                                                                                
Error on line 4: syntax error                                                                                                                                                
Error on line 5: syntax error                                                                                                                                                
Error processing entries before line 6: Declaration error for m: attempt to use undefined variable                                                                           
Error processing entries before line 6: Declaration error for n: attempt to use undefined variable                                                                           
Error processing entries before line 6: Declaration error for k: attempt to use undefined variable                                                                           
Error processing entries before line 6: Declaration error for a: attempt to use undefined variable                                                                           
Error processing entries before line 6: Declaration error for filename: attempt to use undefined variable                                                                    
Error on line 6: Declaration error for trim: attempt to use untyped function                                                                                                 
Error on line 6: bad file in open                                                                                                                                            
Error on line 6: non-character control clause                                                                                                                                
Warning on line 9: ignoring text after "end".                                                                                                                                
   read_unformatted_int:                                                                                                                                                     
Error on line 13: syntax error                                                                                                                                               
Error on line 14: syntax error                                                                                                                                               
Error on line 15: syntax error                                                                                                                                               
Error processing entries before line 16: Declaration error for m: attempt to use undefined variable                                                                          
Error processing entries before line 16: Declaration error for n: attempt to use undefined variable                                                                          
Error processing entries before line 16: Declaration error for k: attempt to use undefined variable                                                                          
Error processing entries before line 16: Declaration error for a: attempt to use undefined variable                                                                          
Error processing entries before line 16: Declaration error for filename: attempt to use undefined variable                                                                   
Error on line 16: Declaration error for trim: attempt to use untyped function                                                                                                
Error on line 16: bad file in open                                                                                                                                           
Error on line 16: non-character control clause                                                                                                                               
Warning on line 19: ignoring text after "end".                                                                                                                               
   read_unformatted_mixed:                                                                                                                                                   
Error on line 23: syntax error                                                                                                                                               
Error on line 24: syntax error                                                                                                                                               
Error on line 25: syntax error                                                                                                                                               
Error on line 26: syntax error                                                                                                                                               
Error processing entries before line 27: Declaration error for m: attempt to use undefined variable                                                                          
Error processing entries before line 27: Declaration error for n: attempt to use undefined variable                                                                          
Error processing entries before line 27: Declaration error for k: attempt to use undefined variable                                                                          
Error processing entries before line 27: Declaration error for a: attempt to use undefined variable                                                                          
Error processing entries before line 27: Declaration error for b: attempt to use undefined variable                                                                          
Error processing entries before line 27: Declaration error for filename: attempt to use undefined variable                                                                   
Error on line 27: Declaration error for trim: attempt to use untyped function                                                                                                
Error on line 27: bad file in open                                                                                                                                           
Error on line 27: non-character control clause                                                                                                                               
Warning on line 30: ignoring text after "end".                                                                                                                               
Traceback (most recent call last):                                                                                                                                           
  File "/tmp/tmpve9euhz9/gfortran", line 632, in <module>                                                                                                                    
    compiler_main()                                                                                                                                                          
  File "/tmp/tmpve9euhz9/gfortran", line 628, in compiler_main                                                                                                               
    sys.exit(handle_command(args, build_args))                                                                                                                               
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                                                
  File "/tmp/tmpve9euhz9/gfortran", line 596, in handle_command                                                                                                              
    tmp = replay_f2c(line)                                                                                                                                                   
          ^^^^^^^^^^^^^^^^                                                                                                                                                   
  File "/tmp/tmpve9euhz9/_f2c_fixes.py", line 184, in replay_f2c                                                                                                             
    subprocess.check_call(                                                                                                                                                   
  File "/usr/local/lib/python3.12/subprocess.py", line 413, in check_call                                                                                                    
    raise CalledProcessError(retcode, cmd)                                                                                                                                   
subprocess.CalledProcessError: Command '['/src/packages/scipy/build/scipy-1.14.0/f2c/src/f2c', '-R']' returned non-zero exit status 1.

@lucascolley
Copy link

I feel that the functionality might not be worth fixing too much for Pyodide – we could either let that be a static_library, or remove the extension module altogether, what do you think?

I'm not sure, probably best to defer to @steppi on that one

@agriyakhetarpal
Copy link
Member Author

I'm not facing the error in CI, i.e., ModuleNotFoundError: No module named 'scipy.io.tests', when testing locally – I will continue to debug.

@agriyakhetarpal
Copy link
Member Author

The test failure for Firefox is unrelated – I increased the PyArrow timeout to six times the original value in 828a08f. I'm assuming that a value of 120 means 120 seconds and not milliseconds. Probably overkill, but it makes the timeout statistically unlikely 🤷

@ryanking13
Copy link
Member

ryanking13 commented Aug 19, 2024

Cool, thanks @agriyakhetarpal!

could you teach me how you ascertain which symbols are exported by which module (and its dependents)?

I think you've already figured it out, but FWIW, I use auditwheel-emscripten to list all symbols in the scipy wheel and search which .so files contains the problematic symbol.

pip install auditwheel-emscripten
pyodide auditwheel imports <scipy-wheel>

@ryanking13
Copy link
Member

ryanking13 commented Aug 19, 2024

because f2py is required as an executable and it doesn't seem to be present on PATH when NumPy's WASM wheel is built, because (I think) the Pyodide build procedure doesn't install NumPy after it has been built and when it is building SciPy.

I think we need to fix this somehow... we ignore numpy even if it is specified as a build requirement in the pyproject.toml (code pointer, but it has been a problem for a few use cases (#4160).

@agriyakhetarpal
Copy link
Member Author

agriyakhetarpal commented Aug 19, 2024

Thanks for the super quick review, @ryanking13! I did run auditwheel-emscripten later on, and it does corroborate with the findings you suggest – linking OpenBLAS with _slsqp was the solution, but I did try to link some more modules and remove them later just to see if they resolved any of the other symbol visibility issues that we have marked as xfailed – I didn't have much success. Maybe I'll go into more depth the next time something gets rewritten in C/C++ in SciPy upstream (scipy/scipy#18566).

I have faced #4160 before with some other packages that I was updating that had a dependency on NumPy, so thanks for the pointer. Either way, I'm not super satisfied with the patch, and I wouldn't suggest reverting something in SciPy that made their lives happy just so that it makes ours happy too – so, one way to work around the mess could be to write a Python script for this purpose that would go through the meson.build files recursively and replace the f2py generators with these older module equivalents (even if we need to hardcode their names, that's alright), running after all the patches have been applied. This way, all our patches stay fresh, and we don't need to have an order around them in case we need to write more patches. If there are better alternatives to this, I'd be keen on exploring those.

@ryanking13
Copy link
Member

If there are better alternatives to this, I'd be keen on exploring those.

Let me see if I can fix it in pyodide-build side.

@agriyakhetarpal
Copy link
Member Author

If there are better alternatives to this, I'd be keen on exploring those.

Let me see if I can fix it in pyodide-build side.

Sure, thanks! I saw this comment a little late and was working on my script-based idea in the meantime, but ultimately anything is better than a script that we need to keep maintaining.

@ilayn
Copy link

ilayn commented Aug 21, 2024

Maybe I'll go into more depth the next time something gets rewritten in C/C++ in SciPy upstream

It's L-BFGS-B and ARPACK on its way. Should it be SLSQP next? Otherwise will be PROPACK.

@steppi
Copy link

steppi commented Aug 21, 2024

I feel that the functionality might not be worth fixing too much for Pyodide – we could either let that be a static_library, or remove the extension module altogether, what do you think?

I'm not sure, probably best to defer to @steppi on that one

Sorry, I missed the ping while traveling. If it's too much trouble to get the shared library working, I'd prefer removing the special error handling functionality altogether rather than shipping a broken version that only works for half of the functions.

@agriyakhetarpal
Copy link
Member Author

It's L-BFGS-B and ARPACK on its way. Should it be SLSQP next? Otherwise will be PROPACK.

Hi @ilayn – pinging @lesteve who would have more experience and can answer this better than I would, since he has historically maintained the SciPy test suite for Pyodide in a separate repository at https://github.com/lesteve/scipy-tests-pyodide (though it now runs with the [scipy] commit marker in Pyodide). I would suggest PROPACK, though, since we have some function signature mismatches with it that we currently skip.

Sorry, I missed the ping while traveling. If it's too much trouble to get the shared library working, I'd prefer removing the special error handling functionality altogether rather than shipping a broken version that only works for half of the functions.

No worries, @steppi. I converted the shared library to a static one to allow compilation to proceed, and fortunately, all the tests passed, we're not seeing anything problematic.

@lesteve
Copy link
Contributor

lesteve commented Aug 22, 2024

Hi @ilayn – pinging @lesteve who would have more experience and can answer this better than I would, since he has historically maintained the SciPy test suite for Pyodide in a separate repository at lesteve/scipy-tests-pyodide (though it now runs with the [scipy] commit marker in Pyodide). I would suggest PROPACK, though, since we have some function signature mismatches with it that we currently skip.

No strong opinion on this, I would think that making Pyodide's life easier for Scipy support is only a small part of the story behind the Fortran rewrite.

@ilayn
Copy link

ilayn commented Aug 22, 2024

No strong opinion on this, I would think that making Pyodide's life easier for Scipy support is only a small part of the story behind the Fortran rewrite.

Definitely and at the same time, we can make life easier by attacking the more problematic ones earlier for Pyodide. For me, the order does not matter, they are all excessively boring work, but it might matter for you.

But I guess we tackled the bigger problems so we are at the noise level in terms of preference which is good news for me. I'll see which one is a quicker win then.

Copy link
Member

@hoodmane hoodmane left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@agriyakhetarpal
Copy link
Member Author

Thanks for the reviews! I initially thought I could wait until we can get the install tags functionality working, but I think that is not a blocker because we remove the tests away anyway using unvendor-tests: true; the install tags (if we get it to work) would just not build the test modules any time soon. If Ralf has no other comments on these changes, then we can merge this and I can get started with SciPy v1.14.1 that just came out – I've just been playing catch up over the past week 😁

@rgommers
Copy link
Contributor

This seems fine to me to merge. I'll comment on the f2py generator issue higher up - that patch isn't desirable, but let's not let that block a merge, hopefully we can figure that one out and remove the patch again later.

@agriyakhetarpal agriyakhetarpal merged commit 070eb8d into pyodide:main Aug 23, 2024
@agriyakhetarpal agriyakhetarpal deleted the feat/package/scipy-1.14.0 branch August 23, 2024 07:46
@agriyakhetarpal
Copy link
Member Author

Thanks, Ralf! Merged this, then. I'll put up a PR for the next version.

@agriyakhetarpal agriyakhetarpal mentioned this pull request Aug 23, 2024
2 tasks
lagru added a commit to scikit-image/scikit-image that referenced this pull request Sep 15, 2024
…sting (#7525)

This PR follows up on changes made in gh-7350. Here's a small, point-wise summary noting the changes here:

- It updates the Emscripten/Pyodide CI job added in gh-7350 and removes the workaround JavaScript-based test suite file, since we fixed the `s_cmp` OpenBLAS unresolved symbol coming from SciPy upstream, having updated SciPy in-tree in Pyodide (see pyodide/pyodide#4719, pyodide/pyodide#5012, pyodide/pyodide#5031, and more). This should make the testing slightly cleaner than before, and the test suite now runs till the end without any Pyodide fatal errors being reported.
The [Pyodide xbuildenv](https://github.com/pyodide/pyodide/releases/tag/0.27.0a2) can now be used to set up a virtual environment in which the tests can be run in the same way they were before.
The [`pyodide-build` tool](https://github.com/pyodide/pyodide-build) has been unvendored from the Pyodide repository and now infers the Pyodide version from the releases, downloading the relevant files from the GitHub release. Hence, the `PYODIDE_VERSION` environment variable is no longer required.
- There were some tests that have been failing on 32-bit platforms, which were last discussed quite a while ago: #3091. They surprisingly passed in a WASM 32-bit environment here without issues, which is great. I have updated the skipping conditions to accommodate this.
- There's a known problem with the pytest bytecode generation when running the tests with the xbuildenv interpreter – I disabled the pytest internal cache plugin to fix that, but ignoring the warning (pypa/cibuildwheel#1966 (comment)) works equally as well. Please let me know if there is a preference. :)

Additional context

- Pyodide CI support was first discussed in gh-7265.
- At the time of writing, Pyodide 0.27alpha2 is used in the CI job; once 0.27 stable comes out (should be soon) and `cibuildwheel` updates to it, that (plus this PR) will help unblock another PR that I had opened a while back: gh-7440. I can rebase that PR when ready.
- pyodide/pyodide#4871 (comment)

---

Co-authored-by: Lars Grüter <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants