Skip to content
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

Add Windows CI #689

Merged
merged 74 commits into from
May 22, 2024
Merged

Add Windows CI #689

merged 74 commits into from
May 22, 2024

Conversation

jhale
Copy link
Member

@jhale jhale commented Apr 30, 2024

  • Brings back macOS test.
  • Makes pygraphviz truly optional.
  • All C builds done in C17 standard mode.
  • Support for Visual C compiler on Windows (does not support _Complex).
  • Does not preclude use of ffcx on Windows for complex code generation with another compiler invoked via e.g. CMake or at the command line.

@jhale jhale added packaging ci Tasks related to Continuous Integration labels Apr 30, 2024
@minrk
Copy link
Contributor

minrk commented May 21, 2024

is there a possibility option to use clang on Windows via CFFI?

clang is available on Windows, though I've never used it, so don't know what the implications would be. I believe if you use msvc, it would means folks need to install a compiler outside of conda. I think clang should avoid this, but there may still be an SDK requirement, I'm not sure.

Question is: what packages would need to use clang:

  • all fenics packages (basix, dolfinx)?
  • none, just the runtime requirement?

It's going to take me a bit to figure out testing beyond basix on conda-forge, since the dependency means the unreleased builds need to be published somewhere that's not the conda-forge default channel, so downstream can depend on them.

@jhale
Copy link
Member Author

jhale commented May 21, 2024

is there a possibility option to use clang on Windows via CFFI?

clang is available on Windows, though I've never used it, so don't know what the implications would be. I believe if you use msvc, it would means folks need to install a compiler outside of conda. I think clang should avoid this, but there may still be an SDK requirement, I'm not sure.

Question is: what packages would need to use clang:

  • all fenics packages (basix, dolfinx)?
  • none, just the runtime requirement?

It's going to take me a bit to figure out testing beyond basix on conda-forge, since the dependency means the unreleased builds need to be published somewhere that's not the conda-forge default channel, so downstream can depend on them.

I took a look at how FFCx is currently using cffi.compile() and on Windows MSVC is the only option without implementing our own JIT compiler wrappers (which I don't want to do, unless it is absolutely necessary) - so users will need to install MSVC. Most of our users will be covered by the Community License anyway.

This issue (how can I use a different compiler with cffi?) is discussed here:

https://foss.heptapod.net/pypy/cffi/-/issues/560

Our only runtime dependency on a compiler is when using CFFI via FFCx, but it is an important core feature and cannot be skipped.

https://github.com/conda-forge/cffi-feedstock/blob/main/recipe/meta.yaml

You can see here there is no runtime dependency on a C compiler, so it must be assumed provided by the system.

@jhale
Copy link
Member Author

jhale commented May 21, 2024

On the last point, @chrisrichardson has a Windows machine setup for development, so perhaps we could work together to try a conda build locally?

@minrk
Copy link
Contributor

minrk commented May 21, 2024

That's possible. I'm going to try to download the artifacts from unmerged conda-forge CI and upload them to my channel, which should work, but there seems to be a hiccup with downloading the artifacts right now.

@minrk
Copy link
Contributor

minrk commented May 21, 2024

I asked, and even with clang, users would need Windows SDKs to compile, so there would be little benefit to depending on clang instead of msvc.

@jhale
Copy link
Member Author

jhale commented May 21, 2024

Thanks! I read the thread - we can revisit clang as an option at a later date. For now MSVC2022 using cl.exe will be the only officially supported options on Windows.

@jhale
Copy link
Member Author

jhale commented May 21, 2024

Just to clarify a few points from https://conda.discourse.group/t/runtime-requirement-for-c-compiler-on-windows/614/3

  • FFCx has a runtime dependency on a C (not C++) compiler implicitly via CFFI when using our JIT compilation.
  • Our demo runner for testing has a dependency on a C compiler, but that is not strictly necessary for a user install. If a user creates .c and .h files via ffcx command line they will need a C compiler to build something with them but I hope that is self-explanatory.
  • We do not link with anything other than the standard links required by C/CFFI (stdc, Python) etc. and libm (only on Linux/Unix platforms). So there is no linking with Basix or DOLFINx.

@minrk
Copy link
Contributor

minrk commented May 21, 2024

Thanks! That clarifies things.

@jhale
Copy link
Member Author

jhale commented May 21, 2024

Great. This patch is now ready for final review and preliminary testing in Conda.

@minrk
Copy link
Contributor

minrk commented May 22, 2024

Haven't quite worked out all the kinks in getting basix from my channel into conda-forge CI, but so far looks like ffcx (d3ecb54) works fine on Windows in conda-forge with no modifications.

assert (
os.system(
f"cd {demo_dir} && "
f"gcc -I../ffcx/codegeneration "
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
f"gcc -I../ffcx/codegeneration "
f"cc -I../ffcx/codegeneration "

Copy link
Contributor

Choose a reason for hiding this comment

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

fwiw, I think cc = os.environ.get("CC", sysconfig.get_config_var("CC")) is more likely to get the right thing and accepts the ubiquitous standard env override.

Copy link
Member Author

@jhale jhale May 22, 2024

Choose a reason for hiding this comment

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

On balance I'd rather go with a combination cc = os.environ.get("CC", "cc") - what Python thinks about how to build extension modules doesn't seem hugely relevant to this test which is about our C/C++ pipeline.

@minrk
Copy link
Contributor

minrk commented May 22, 2024

All tests pass on conda on Windows without any special handling: conda-forge/fenics-ffcx-feedstock#7

Windows folks should be able to test installation with conda with:

conda install -c conda-forge -c minrk/label/fenics-windows fenics-ffcx=0.9.0.dev

@jhale
Copy link
Member Author

jhale commented May 22, 2024

This is now ready to merge.

Copy link
Member

@garth-wells garth-wells left a comment

Choose a reason for hiding this comment

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

Nice!

@@ -22,40 +22,75 @@ jobs:
matrix:
os: [ubuntu-latest]
python-version: ['3.9', '3.10', '3.11', '3.12']
include:
- os: windows-latest
python-version: '3.11'
Copy link
Member

Choose a reason for hiding this comment

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

Any reason to test with 3.11 rather than 3.12?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not really, just providing some coverage because I will run against 3.12 on Windows elsewhere, e.g. DOLFINx.

@@ -64,10 +99,15 @@ jobs:
# Use always() to always run this step to publish test results
# when there are test failures
if: always()

- name: Setup cl.exe (Windows)
Copy link
Member

Choose a reason for hiding this comment

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

Is cl.exe clang?

Copy link
Member Author

@jhale jhale May 22, 2024

Choose a reason for hiding this comment

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

No, it's Microsoft's Visual C Compiler (MSVC).

Note that Microsoft also offer clang-cl.exe which is a wrapper over clang to a provide drop-in replacement for cl.exe. This looked exciting in the first instance, because it supports _Complex. However, clang-cl.exe is not supported by Conda or CFFI, where MSVC is the only supported option today on Windows.

I did however add a test of clang-cl.exe to our C demo tests, and it works fine.

@@ -17,6 +17,10 @@
@pytest.mark.parametrize("scalar_type", ["float64", "float32", "complex128", "complex64"])
def test_demo(file, scalar_type):
"""Test a demo."""
if sys.platform.startswith("win32") and "complex" in scalar_type:
# Skip complex demos on win32
pytest.skip(reason="_Complex not supported on Windows")
Copy link
Member

Choose a reason for hiding this comment

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

What a pain . . . .

Copy link
Member Author

@jhale jhale May 22, 2024

Choose a reason for hiding this comment

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

Indeed, MSVC's lack of _Complex support has been the only major issue blocking a straightforward port.

@jhale jhale added this pull request to the merge queue May 22, 2024
Merged via the queue into main with commit 86a8cc2 May 22, 2024
13 checks passed
@jhale jhale deleted the jhale/windows-test branch May 22, 2024 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ci Tasks related to Continuous Integration packaging
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants