Skip to content

Commit

Permalink
Merge branch 'flatironinstitute:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
oneilm authored Sep 26, 2024
2 parents 017c0a9 + f814e99 commit a24196f
Show file tree
Hide file tree
Showing 10 changed files with 296 additions and 23 deletions.
11 changes: 1 addition & 10 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
name: Python Build

on:
push:
branches:
- master
tags:
- v*
- py_v*
pull_request:
branches:
- master
on: workflow_dispatch

jobs:
Linux:
Expand Down
35 changes: 35 additions & 0 deletions .github/workflows/python_cmake.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Python cmake build test

on:
push:
branches:
- master
tags:
- v*
- py_v*
pull_request:
branches:
- master

jobs:
Linux:
runs-on: ubuntu-latest
container: quay.io/pypa/manylinux_2_28_x86_64:latest

steps:
- uses: actions/checkout@v4

- name: install gfortran
run: |
yum install -y gcc-toolset-12.x86_64
- name: Compile and install python bindings
run: |
scl enable gcc-toolset-12 bash
/opt/python/cp311-cp311/bin/python -m pip install .
- name: Test python bindings
run: |
/opt/python/cp311-cp311/bin/python -m pip install pytest
/opt/python/cp311-cp311/bin/python -m pytest -s python/test
180 changes: 180 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# set minimum cmake version
cmake_minimum_required(VERSION 3.18)

# project name and language
project(fmm3d LANGUAGES C Fortran)

# verbose makefile
set(CMAKE_VERBOSE_MAKEFILE ON)

# Safety net
if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
message(
FATAL_ERROR
"In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.\n"
)
endif()

# Grab Python
find_package(Python REQUIRED COMPONENTS Interpreter Development.Module NumPy)
# Grab OpenMP
find_package(OpenMP REQUIRED)
if (OpenMP_Fortran_FOUND)
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${OpenMP_Fortran_FLAGS}")
endif()

# Grab the variables from a local Python installation
# F2PY headers
execute_process(
COMMAND "${Python_EXECUTABLE}"
-c "import numpy.f2py; print(numpy.f2py.get_include())"
OUTPUT_VARIABLE F2PY_INCLUDE_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)

# build static lib libfmm3d.a
# source files for libfmm3d.a
file(GLOB_RECURSE source_list "src/*.f" "src/*.f90")
#message(${source_list})
# remove fast kernels and tree_lr_3d.f
list(FILTER source_list EXCLUDE REGEX ".*_fast\\.f$|.*tree_lr_3d\\.f")
#message(${source_list})
# add fmm3d static lib
add_library(fmm3d STATIC ${source_list})
#compiler options
target_compile_options(fmm3d PRIVATE -fPIC -O3 -march=native -funroll-loops -std=legacy -w)

# Print out the discovered paths
include(CMakePrintHelpers)
cmake_print_variables(Python_INCLUDE_DIRS)
cmake_print_variables(F2PY_INCLUDE_DIR)
cmake_print_variables(Python_NumPy_INCLUDE_DIRS)

# extensions variables
# hfmm3d_fortran
set(hfmm_module_name "hfmm3d_fortran")
set(hfmm_fortran_src_file ${CMAKE_SOURCE_DIR}/src/Helmholtz/hfmm3dwrap.f
${CMAKE_SOURCE_DIR}/src/Helmholtz/hfmm3dwrap_vec.f
${CMAKE_SOURCE_DIR}/src/Helmholtz/helmkernels.f)
set(f2py_helm_module_c "${hfmm_module_name}module.c")
# lfmm3d_fortran
set(lfmm_module_name "lfmm3d_fortran")
set(lfmm_fortran_src_file ${CMAKE_SOURCE_DIR}/src/Laplace/lfmm3dwrap.f
${CMAKE_SOURCE_DIR}/src/Laplace/lfmm3dwrap_vec.f
${CMAKE_SOURCE_DIR}/src/Laplace/lapkernels.f)
set(f2py_lap_module_c "${lfmm_module_name}module.c")
# emfmm3d_fortran
set(emfmm_module_name "emfmm3d_fortran")
set(emfmm_fortran_src_file ${CMAKE_SOURCE_DIR}/src/Helmholtz/hfmm3dwrap.f
${CMAKE_SOURCE_DIR}/src/Helmholtz/hfmm3dwrap_vec.f
${CMAKE_SOURCE_DIR}/src/Helmholtz/helmkernels.f
${CMAKE_SOURCE_DIR}/src/Maxwell/emfmm3d.f90)
set(f2py_em_module_c "${emfmm_module_name}module.c")
# stfmm3d_fortran
set(stfmm_module_name "stfmm3d_fortran")
set(stfmm_fortran_src_file ${CMAKE_SOURCE_DIR}/src/Laplace/lfmm3dwrap.f
${CMAKE_SOURCE_DIR}/src/Laplace/lfmm3dwrap_vec.f
${CMAKE_SOURCE_DIR}/src/Laplace/lapkernels.f
${CMAKE_SOURCE_DIR}/src/Stokes/stfmm3d.f
${CMAKE_SOURCE_DIR}/src/Stokes/stokkernels.f)
set(f2py_st_module_c "${stfmm_module_name}module.c")

# Generate extensions' sources
# hfmm3d_fortran
add_custom_target(
hfmm_genpyf
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${f2py_helm_module_c}"
)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${f2py_helm_module_c}" "${CMAKE_CURRENT_BINARY_DIR}/${hfmm_module_name}-f2pywrappers2.f90"
COMMAND ${Python_EXECUTABLE} -m "numpy.f2py"
-m "hfmm3d_fortran"
${hfmm_fortran_src_file}
--lower
DEPENDS ${hfmm_fortran_src_file} # Fortran source
)
# lfmm3d_fortran
add_custom_target(
lfmm_genpyf
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${f2py_lap_module_c}"
)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${f2py_lap_module_c}" "${CMAKE_CURRENT_BINARY_DIR}/${lfmm_module_name}-f2pywrappers2.f90"
COMMAND ${Python_EXECUTABLE} -m "numpy.f2py"
-m "lfmm3d_fortran"
${lfmm_fortran_src_file}
--lower
DEPENDS ${lfmm_fortran_src_file} # Fortran source
)
# emfmm3d_fortran
add_custom_target(
emfmm_genpyf
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${f2py_em_module_c}"
)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${f2py_em_module_c}" "${CMAKE_CURRENT_BINARY_DIR}/${emfmm_module_name}-f2pywrappers2.f90"
COMMAND ${Python_EXECUTABLE} -m "numpy.f2py"
-m "emfmm3d_fortran"
${emfmm_fortran_src_file}
--lower
DEPENDS ${emfmm_fortran_src_file} # Fortran source
)
# stfmm3d_fortran
add_custom_target(
stfmm_genpyf
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${f2py_st_module_c}"
)
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${f2py_st_module_c}" "${CMAKE_CURRENT_BINARY_DIR}/${stfmm_module_name}-f2pywrappers2.f90"
COMMAND ${Python_EXECUTABLE} -m "numpy.f2py"
-m "stfmm3d_fortran"
${stfmm_fortran_src_file}
--lower
DEPENDS ${stfmm_fortran_src_file} # Fortran source
)

# Set up extensions targets
# hfmm3d_fortran
Python_add_library(hfmm3d_fortran MODULE WITH_SOABI
"${CMAKE_CURRENT_BINARY_DIR}/${f2py_helm_module_c}" # Generated
"${F2PY_INCLUDE_DIR}/fortranobject.c" # From NumPy
"${hfmm_fortran_src_file}" # Fortran source(s)
)
# lfmm3d_fortran
Python_add_library(lfmm3d_fortran MODULE WITH_SOABI
"${CMAKE_CURRENT_BINARY_DIR}/${f2py_lap_module_c}" # Generated
"${F2PY_INCLUDE_DIR}/fortranobject.c" # From NumPy
"${lfmm_fortran_src_file}" # Fortran source(s)
)
# emfmm3d_fortran
Python_add_library(emfmm3d_fortran MODULE WITH_SOABI
"${CMAKE_CURRENT_BINARY_DIR}/${f2py_em_module_c}" # Generated
"${F2PY_INCLUDE_DIR}/fortranobject.c" # From NumPy
"${emfmm_fortran_src_file}" # Fortran source(s)
)
# stfmm3d_fortran
Python_add_library(stfmm3d_fortran MODULE WITH_SOABI
"${CMAKE_CURRENT_BINARY_DIR}/${f2py_st_module_c}" # Generated
"${F2PY_INCLUDE_DIR}/fortranobject.c" # From NumPy
"${stfmm_fortran_src_file}" # Fortran source(s)
)

# Dependencies for extensions
# hfmm3d_fortran
target_link_libraries(hfmm3d_fortran PRIVATE Python::NumPy fmm3d)
add_dependencies(hfmm3d_fortran hfmm_genpyf)
target_include_directories(hfmm3d_fortran PRIVATE "${F2PY_INCLUDE_DIR}")
# lfmm3d_fortran
target_link_libraries(lfmm3d_fortran PRIVATE Python::NumPy fmm3d)
add_dependencies(lfmm3d_fortran lfmm_genpyf)
target_include_directories(lfmm3d_fortran PRIVATE "${F2PY_INCLUDE_DIR}")
# emfmm3d_fortran
target_link_libraries(emfmm3d_fortran PRIVATE Python::NumPy fmm3d)
add_dependencies(emfmm3d_fortran emfmm_genpyf)
target_include_directories(emfmm3d_fortran PRIVATE "${F2PY_INCLUDE_DIR}")
# stfmm3d_fortran
target_link_libraries(stfmm3d_fortran PRIVATE Python::NumPy fmm3d)
add_dependencies(stfmm3d_fortran stfmm_genpyf)
target_include_directories(stfmm3d_fortran PRIVATE "${F2PY_INCLUDE_DIR}")

add_subdirectory(python)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Flatiron Institute Fast Multipole Libraries
[![Actions status](https://github.com/flatironinstitute/FMM3D/workflows/Python%20Build/badge.svg)](https://github.com/flatironinstitute/FMM3D/actions)
[![Actions status](https://github.com/flatironinstitute/FMM3D/actions/workflows/python_cmake.yml/badge.svg)](https://github.com/flatironinstitute/FMM3D/actions)

This codebase is a set of libraries to compute N-body interactions
governed by the Laplace and Helmholtz equations, to a specified
Expand Down
21 changes: 18 additions & 3 deletions julia/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,36 @@ Flatiron Institute's `FMM3D` library.

## Using FMM3D.jl

For now, FMM3D.jl can be obtained by downloading this
`FMM3D.jl` is now registered in the Julia General registry, so you can install it in Julia 1.6 or later.
Press `]` in Julia REPL to enter the package manager and then enter:
```julia
pkg> add FMM3D
```
then the package should be installed automatically.

You can then use the package with

```julia
julia> using FMM3D
```

It can also be obtained by downloading this
git repository and a recent version of julia
(1.6 or later is required). Then, from the
root directory (the parent directory of the
julia subdirectory) run the following in
julia:

```julia
Pkg.add(url=".",subdir="julia")
julia> using Pkg

julia> Pkg.add(url=".",subdir="julia")
```

You can test the package with

```julia
Pkg.test("FMM3D")
julia> Pkg.test("FMM3D")
```

## Contributing
Expand Down
34 changes: 34 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[build-system]
requires = [
"scikit-build-core >= 0.4.3",
"cmake >= 3.19",
"numpy >= 1.12.0",
]

build-backend = "scikit_build_core.build"

[project]
name = "fmm3dpy"
description = "Python bindings for the FMM3D library"
readme = "README.md"
requires-python = ">=3.8"
dependencies = ["numpy >= 1.12.0"]
dynamic = ["version"]

[tool.scikit-build]
# Protect the configuration against future changes in scikit-build-core
minimum-version = "0.4"
# Setuptools-style build caching in a local directory
build-dir = "build/{wheel_tag}"

cmake.targets = ["fmm3d", "hfmm3d_fortran", "lfmm3d_fortran", "emfmm3d_fortran", "stfmm3d_fortran"]

wheel.packages = ["python/fmm3dpy"]

[tool.scikit-build.metadata.version]
provider = "scikit_build_core.metadata.regex"
input = "python/fmm3dpy/__init__.py"

[tool.cibuildwheel]
# Necessary to see build output from the actual compilation
build-verbosity = 1
5 changes: 5 additions & 0 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
if (WIN32)
install(TARGETS hfmm3d_fortran lfmm3d_fortran emfmm3d_fortran stfmm3d_fortran DESTINATION fmm3dpy RUNTIME DESTINATION fmm3dpy)
else ()
install(TARGETS hfmm3d_fortran lfmm3d_fortran emfmm3d_fortran stfmm3d_fortran DESTINATION fmm3dpy)
endif ()
1 change: 1 addition & 0 deletions python/fmm3dpy/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from .fmm3d import hfmm3d,lfmm3d,emfmm3d,stfmm3d,h3ddir,l3ddir,em3ddir,st3ddir,comperr,Output
__version__ = '1.0.4'
16 changes: 8 additions & 8 deletions src/Laplace/lapkernels.f
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
c for a collection of charge sources to a
c collection of targets
c
c l3ddirectch: direct calculation of potential and gradients
c for a collection of charge sources to a
c l3ddirectch: direct calculation of potential, gradients and
c hessians for a collection of charge sources to a
c collection of targets
c
c l3ddirectdp: direct calculation of potential for a collection
Expand All @@ -18,21 +18,21 @@
c for a collection of dipole sources to a
c collection of targets
c
c l3ddirectdh: direct calculation of potential and gradients
c for a collection of dipole sources to a
c l3ddirectdh: direct calculation of potential, gradients and
c hessians for a collection of dipole sources to a
c collection of targets
c
c l3ddirectcdp: direct calculation of potential for a collection
c of charge and dipole sources to a collection
c of targets
c
c l3ddirectdg: direct calculation of potential and gradients
c l3ddirectcdg: direct calculation of potential and gradients
c for a collection of charge and dipole sources to
c a collection of targets
c
c l3ddirectdh: direct calculation of potential and gradients
c for a collection of charge and dipole sources to
c a collection of targets
c l3ddirectcdh: direct calculation of potential, gradients and
c hessians for a collection of charge and dipole
c sources to a collection of targets
c
c
c
Expand Down
14 changes: 13 additions & 1 deletion src/Laplace/lapkernels_fast.f
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,33 @@
c for a collection of charge sources to a
c collection of targets
c
c l3ddirectch: direct calculation of potential, gradients and
c hessians for a collection of charge sources to a
c collection of targets
c
c l3ddirectdp: direct calculation of potential for a collection
c of dipole sources to a collection of targets
c
c l3ddirectdg: direct calculation of potential and gradients
c for a collection of dipole sources to a
c collection of targets
c
c l3ddirectdh: direct calculation of potential, gradients and
c hessians for a collection of dipole sources to a
c collection of targets
c
c l3ddirectcdp: direct calculation of potential for a collection
c of charge and dipole sources to a collection
c of targets
c
c l3ddirectdg: direct calculation of potential and gradients
c l3ddirectcdg: direct calculation of potential and gradients
c for a collection of charge and dipole sources to
c a collection of targets
c
c l3ddirectcdh: direct calculation of potential, gradients and
c hessians for a collection of charge and dipole
c sources to a collection of targets
c
c
c
c
Expand Down

0 comments on commit a24196f

Please sign in to comment.