From a836fdefbe13ebf5062ad2b1a4515745faf22ea1 Mon Sep 17 00:00:00 2001 From: lukaswittmann Date: Fri, 22 Nov 2024 09:20:13 +0100 Subject: [PATCH 01/15] Crude meson infrastructure --- config/meson.build | 34 +++++++++++++++++++++++ meson.build | 68 ++++++++++++++++++++++++++++++++++++++++++++++ meson_options.txt | 47 ++++++++++++++++++++++++++++++++ tests/meson.build | 46 +++++++++++++++++++++++++++++++ 4 files changed, 195 insertions(+) create mode 100644 config/meson.build create mode 100644 meson.build create mode 100644 meson_options.txt create mode 100644 tests/meson.build diff --git a/config/meson.build b/config/meson.build new file mode 100644 index 00000000..4dd7aafc --- /dev/null +++ b/config/meson.build @@ -0,0 +1,34 @@ +# This file is part of dftd4. +# SPDX-Identifier: LGPL-3.0-or-later +# +# dftd4 is free software: you can redistribute it and/or modify it under +# the terms of the Lesser GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# dftd4 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# Lesser GNU General Public License for more details. +# +# You should have received a copy of the Lesser GNU General Public License +# along with dftd4. If not, see . + +os = host_machine.system() +fc = meson.get_compiler('fortran') +cc = fc +# cc = meson.get_compiler('c') +fc_id = fc.get_id() + +if fc_id == 'gcc' + add_project_arguments( + '-ffree-line-length-none', + '-fbacktrace', + language: 'fortran', + ) +elif fc_id == 'intel' + add_project_arguments( + '-traceback', + language: 'fortran', + ) +endif diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..3dd49e72 --- /dev/null +++ b/meson.build @@ -0,0 +1,68 @@ +# Minimum version and project definition +project('ddX', + 'fortran', + 'cpp', + version: '0.6.0', + license: 'LGPL-3.0-or-later', + default_options: [ + 'buildtype=debugoptimized', + 'default_library=both', + ], +) + +install = not (meson.is_subproject() and get_option('default_library') == 'static') +has_cc = add_languages('c', required: get_option('api') or get_option('python'), native: false) + +# Retrieve Fortran and C++ compiler objects +fortran_compiler = meson.get_compiler('fortran') +cxx_compiler = meson.get_compiler('cpp') + +# Find dependencies: BLAS, LAPACK, OpenMP +blas_dep = dependency('blas', required: true) +lapack_dep = dependency('lapack', required: true) +openmp_dep = dependency('openmp', required: true) + +subdir('config') + +# Create a ddX library +ddx_library = library( + 'ddX', + sources: [ + 'src/ddx.f90', + 'src/cbessel.f90', + 'src/ddx_driver.f90', + 'src/ddx_lpb_core.f90', + 'src/ddx_workspace.f90', + 'src/ddx_errors.f90', + 'src/ddx_lpb.f90', + 'src/llgnew.f', + 'src/ddx_cinterface.f90', + 'src/ddx_multipolar_solutes.f90', + 'src/ddx_constants.f90', + 'src/ddx_gradients.f90', + 'src/ddx_operators.f90', + 'src/ddx_core.f90', + 'src/ddx_parameters.f90', + 'src/ddx_cosmo.f90', + 'src/ddx_harmonics.f90', + 'src/ddx_pcm.f90', + 'src/ddx_definitions.f90', + 'src/ddx_legacy.f90', + 'src/ddx_solvers.f90' + ], + dependencies: [blas_dep, lapack_dep, openmp_dep], +) + +# Export dependency for other projects and test suite +ddx_dep = declare_dependency(link_with: ddx_library) + +# Add executable target for ddX (if needed) +executable_target = executable( + 'ddX_exec', + sources: ['src/ddx_driver.f90'], + link_with: [ddx_library, ], + dependencies: [blas_dep, lapack_dep, openmp_dep] +) + +# add the testsuite +subdir('tests') \ No newline at end of file diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 00000000..96911885 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,47 @@ +# This file is part of tblite. +# SPDX-Identifier: LGPL-3.0-or-later +# +# tblite is free software: you can redistribute it and/or modify it under +# the terms of the Lesser GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# tblite is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# Lesser GNU General Public License for more details. +# +# You should have received a copy of the Lesser GNU General Public License +# along with tblite. If not, see . + +option( + 'lapack', + type: 'combo', + value: 'auto', + yield: true, + choices: ['auto', 'mkl', 'mkl-rt', 'openblas', 'netlib', 'custom'], + description : 'linear algebra backend', +) + +option( + 'custom_libraries', + type: 'array', + value: [], + yield: true, + description: 'libraries to load for custom linear algebra backend', +) + +option( + 'openmp', + type: 'boolean', + value: true, + yield: true, + description: 'use OpenMP parallelisation', +) + +option( + 'api', + type: 'boolean', + value: true, + description: 'Build C API using iso_c_binding module', +) diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 00000000..124b8a07 --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,46 @@ + +ddx_prefix = '' +# Test sources with their arguments +test_sources = [ + ['ddx_core.f90', []], + ['ddx_operators.f90', []], + ['bessel.f90', []], + ['force.f90', ['Input_force.txt']], + ['ddx_driver.f90', [ + 'data/ddpcm_force_fmm.in', 'data/ddpcm_force_fmm.out', '1E-12', + 'data/ddcosmo_force_fmm.in', 'data/ddcosmo_force_fmm.out', '1E-12' + ]], + ['force_ddlpb.f90', ['data/ddlpb_force.txt']], + ['ddlpb_esolv.f90', ['data/ddlpb_force.txt']], + ['matrix_derivatives.f90', ['data/ddlpb_force.txt']], + ['matrix_adjoint.f90', ['data/ddlpb_force.txt']], + ['matrix_solvers.f90', ['data/ddlpb_force.txt']], + ['m2l.f90', []], + ['multipolar_solutes.f90', []], + ['error.f90', []] +] + +# Create test executables and add tests +foreach source_entry : test_sources + src = source_entry[0] + args = source_entry[1] + executable_name = src.split('.')[0] + + test_executable = executable( + ddx_prefix + executable_name, + src, + dependencies: [blas_dep, lapack_dep, openmp_dep, ddx_dep], # Link to ddx_dep + install: false + ) + + # Add the test with ddX runtime dependency + if args.length() == 0 + test(ddx_prefix + executable_name, test_executable) + else + idx = 0 + foreach arg_set : args + test(ddx_prefix + executable_name + '_' + idx.to_string(), test_executable, args: arg_set.split()) + idx += 1 + endforeach + endif +endforeach \ No newline at end of file From 3f790449563535f4c1a20da8dafd5f1f15add426 Mon Sep 17 00:00:00 2001 From: lukaswittmann Date: Fri, 22 Nov 2024 10:15:15 +0100 Subject: [PATCH 02/15] Tests working, only ddlpb_esolv_0 fails due to ddCOSMO convergence failing --- tests/meson.build | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/tests/meson.build b/tests/meson.build index 124b8a07..13fc0ed7 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,20 +1,21 @@ -ddx_prefix = '' +project_dir = meson.source_root() + +# Test sources with their arguments # Test sources with their arguments test_sources = [ ['ddx_core.f90', []], ['ddx_operators.f90', []], ['bessel.f90', []], - ['force.f90', ['Input_force.txt']], ['ddx_driver.f90', [ - 'data/ddpcm_force_fmm.in', 'data/ddpcm_force_fmm.out', '1E-12', - 'data/ddcosmo_force_fmm.in', 'data/ddcosmo_force_fmm.out', '1E-12' + join_paths(project_dir, 'tests/data/ddpcm_force_fmm.in') + ' ' + join_paths(project_dir, 'tests/data/ddpcm_force_fmm.out') + ' 1E-12', + join_paths(project_dir, 'tests/data/ddcosmo_force_fmm.in') + ' ' + join_paths(project_dir, 'tests/data/ddcosmo_force_fmm.out') + ' 1E-12' ]], - ['force_ddlpb.f90', ['data/ddlpb_force.txt']], - ['ddlpb_esolv.f90', ['data/ddlpb_force.txt']], - ['matrix_derivatives.f90', ['data/ddlpb_force.txt']], - ['matrix_adjoint.f90', ['data/ddlpb_force.txt']], - ['matrix_solvers.f90', ['data/ddlpb_force.txt']], + ['force_ddlpb.f90', [join_paths(project_dir, 'tests/data/ddlpb_force.txt')]], + ['ddlpb_esolv.f90', [join_paths(project_dir, 'tests/data/ddlpb_force.txt')]], + ['matrix_derivatives.f90', [join_paths(project_dir, 'tests/data/ddlpb_force.txt')]], + ['matrix_adjoint.f90', [join_paths(project_dir, 'tests/data/ddlpb_force.txt')]], + ['matrix_solvers.f90', [join_paths(project_dir, 'tests/data/ddlpb_force.txt')]], ['m2l.f90', []], ['multipolar_solutes.f90', []], ['error.f90', []] @@ -27,7 +28,7 @@ foreach source_entry : test_sources executable_name = src.split('.')[0] test_executable = executable( - ddx_prefix + executable_name, + executable_name, src, dependencies: [blas_dep, lapack_dep, openmp_dep, ddx_dep], # Link to ddx_dep install: false @@ -35,11 +36,20 @@ foreach source_entry : test_sources # Add the test with ddX runtime dependency if args.length() == 0 - test(ddx_prefix + executable_name, test_executable) + test(executable_name, test_executable) else idx = 0 foreach arg_set : args - test(ddx_prefix + executable_name + '_' + idx.to_string(), test_executable, args: arg_set.split()) + test( + executable_name + '_' + idx.to_string(), + test_executable, + args: arg_set.split(), + timeout: 240 + ) + + # print out the exact command with argument for each test + message('test ' + idx.to_string() + ' ' + executable_name + ' ' + arg_set) + idx += 1 endforeach endif From 80bd9173e1ca0d13dfb93fa1f02abfbfdb219f73 Mon Sep 17 00:00:00 2001 From: lukaswittmann Date: Tue, 10 Dec 2024 15:25:56 +0100 Subject: [PATCH 03/15] Meson update --- .meson-subproject-wrap-hash.txt | 1 + meson.build | 81 +++++++++++++++++++++++++++++++-- 2 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 .meson-subproject-wrap-hash.txt diff --git a/.meson-subproject-wrap-hash.txt b/.meson-subproject-wrap-hash.txt new file mode 100644 index 00000000..5fe03181 --- /dev/null +++ b/.meson-subproject-wrap-hash.txt @@ -0,0 +1 @@ +23c02f2dc3bd78c024608ca25c933304b62ede67384736d9eb8247e70e1ba05b diff --git a/meson.build b/meson.build index 3dd49e72..f32182ad 100644 --- a/meson.build +++ b/meson.build @@ -12,15 +12,88 @@ project('ddX', install = not (meson.is_subproject() and get_option('default_library') == 'static') has_cc = add_languages('c', required: get_option('api') or get_option('python'), native: false) +fc = meson.get_compiler('fortran') +cc = fc +fc_id = fc.get_id() # Retrieve Fortran and C++ compiler objects fortran_compiler = meson.get_compiler('fortran') cxx_compiler = meson.get_compiler('cpp') # Find dependencies: BLAS, LAPACK, OpenMP -blas_dep = dependency('blas', required: true) -lapack_dep = dependency('lapack', required: true) +# blas_dep = dependency('openblas', required: true) +# lapack_dep = dependency('lapack', required: true) + +lapack_vendor = get_option('lapack') +if lapack_vendor == 'auto' + if fc_id == 'intel' + lapack_vendor = 'mkl' + endif +endif + +lib_deps = [] +if lapack_vendor == 'mkl' + mkl_dep = [] + if fc_id == 'intel' + mkl_dep += cc.find_library('mkl_intel_lp64') + if get_option('openmp') + mkl_dep += cc.find_library('mkl_intel_thread') + endif + elif fc_id == 'gcc' + mkl_dep += cc.find_library('mkl_gf_lp64') + if get_option('openmp') + mkl_dep += cc.find_library('mkl_gnu_thread') + endif + else + error('MKL not supported for this compiler') + endif + if not get_option('openmp') + mkl_dep += cc.find_library('mkl_tbb_thread') + endif + mkl_dep += cc.find_library('mkl_core') + lib_deps += mkl_dep + add_project_arguments(['-DWITH_MKL'], language: 'fortran') +elif lapack_vendor == 'mkl-rt' + mkl_dep = cc.find_library('mkl_rt') + lib_deps += mkl_dep + add_project_arguments(['-DWITH_MKL'], language: 'fortran') +elif lapack_vendor == 'openblas' + blas_dep = dependency('openblas', required: false) + if not blas_dep.found() + blas_dep = cc.find_library('openblas') + endif + lib_deps += blas_dep + if not fc.links('external dsytrs; call dsytrs(); end', dependencies: blas_dep) + lapack_dep = dependency('lapack', required: false) + if not lapack_dep.found() + lapack_dep = cc.find_library('lapack') + endif + lib_deps += lapack_dep + endif + +elif lapack_vendor == 'custom' + foreach lib: get_option('custom_libraries') + lib_deps += cc.find_library(lib) + endforeach + +else + lapack_dep = dependency('lapack', required: false) + if not lapack_dep.found() + lapack_dep = cc.find_library('lapack') + endif + lib_deps += lapack_dep + blas_dep = dependency('blas', required: false) + if not blas_dep.found() + blas_dep = cc.find_library('blas') + endif + lib_deps += blas_dep +endif + openmp_dep = dependency('openmp', required: true) +lib_deps += openmp_dep + + +# dependency('openblas', required: false) subdir('config') @@ -50,7 +123,7 @@ ddx_library = library( 'src/ddx_legacy.f90', 'src/ddx_solvers.f90' ], - dependencies: [blas_dep, lapack_dep, openmp_dep], + dependencies: lib_deps ) # Export dependency for other projects and test suite @@ -61,7 +134,7 @@ executable_target = executable( 'ddX_exec', sources: ['src/ddx_driver.f90'], link_with: [ddx_library, ], - dependencies: [blas_dep, lapack_dep, openmp_dep] + dependencies: lib_deps ) # add the testsuite From 99ced8028410d5b1ab7c11db8f45c3634d6c7ee6 Mon Sep 17 00:00:00 2001 From: lukaswittmann Date: Tue, 11 Mar 2025 10:32:01 +0100 Subject: [PATCH 04/15] Changed meson build for tests so it works as a subproject --- tests/meson.build | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/meson.build b/tests/meson.build index 13fc0ed7..1b462b5f 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,5 +1,5 @@ -project_dir = meson.source_root() +project_dir = meson.current_source_dir() # Test sources with their arguments # Test sources with their arguments @@ -8,14 +8,14 @@ test_sources = [ ['ddx_operators.f90', []], ['bessel.f90', []], ['ddx_driver.f90', [ - join_paths(project_dir, 'tests/data/ddpcm_force_fmm.in') + ' ' + join_paths(project_dir, 'tests/data/ddpcm_force_fmm.out') + ' 1E-12', - join_paths(project_dir, 'tests/data/ddcosmo_force_fmm.in') + ' ' + join_paths(project_dir, 'tests/data/ddcosmo_force_fmm.out') + ' 1E-12' + join_paths(project_dir, 'data/ddpcm_force_fmm.in') + ' ' + join_paths(project_dir, 'data/ddpcm_force_fmm.out') + ' 1E-12', + join_paths(project_dir, 'data/ddcosmo_force_fmm.in') + ' ' + join_paths(project_dir, 'data/ddcosmo_force_fmm.out') + ' 1E-12' ]], - ['force_ddlpb.f90', [join_paths(project_dir, 'tests/data/ddlpb_force.txt')]], - ['ddlpb_esolv.f90', [join_paths(project_dir, 'tests/data/ddlpb_force.txt')]], - ['matrix_derivatives.f90', [join_paths(project_dir, 'tests/data/ddlpb_force.txt')]], - ['matrix_adjoint.f90', [join_paths(project_dir, 'tests/data/ddlpb_force.txt')]], - ['matrix_solvers.f90', [join_paths(project_dir, 'tests/data/ddlpb_force.txt')]], + ['force_ddlpb.f90', [join_paths(project_dir, 'data/ddlpb_force.txt')]], + ['ddlpb_esolv.f90', [join_paths(project_dir, 'data/ddlpb_force.txt')]], + ['matrix_derivatives.f90', [join_paths(project_dir, 'data/ddlpb_force.txt')]], + ['matrix_adjoint.f90', [join_paths(project_dir, 'data/ddlpb_force.txt')]], + ['matrix_solvers.f90', [join_paths(project_dir, 'data/ddlpb_force.txt')]], ['m2l.f90', []], ['multipolar_solutes.f90', []], ['error.f90', []] From d8bc9c6e2aa523995f2dfc87a81f046171212a3c Mon Sep 17 00:00:00 2001 From: lukaswittmann Date: Tue, 11 Mar 2025 13:31:46 +0100 Subject: [PATCH 05/15] Added standalone tests and finishing touches --- meson.build | 202 +++++++++---------- meson_options.txt | 41 ++-- tests/meson.build | 86 ++++---- tests/standalone_tests/meson.build | 62 ++++++ tests/standalone_tests/meson_test_wrapper.in | 7 + 5 files changed, 228 insertions(+), 170 deletions(-) create mode 100644 tests/standalone_tests/meson.build create mode 100755 tests/standalone_tests/meson_test_wrapper.in diff --git a/meson.build b/meson.build index f32182ad..cdc4a4ff 100644 --- a/meson.build +++ b/meson.build @@ -1,129 +1,120 @@ # Minimum version and project definition project('ddX', - 'fortran', - 'cpp', - version: '0.6.0', - license: 'LGPL-3.0-or-later', - default_options: [ - 'buildtype=debugoptimized', - 'default_library=both', - ], + 'fortran', + 'cpp', + version: '0.6.0', + license: 'LGPL-3.0-or-later', + default_options: [ + 'buildtype=debugoptimized', + 'default_library=both', + ], ) install = not (meson.is_subproject() and get_option('default_library') == 'static') -has_cc = add_languages('c', required: get_option('api') or get_option('python'), native: false) fc = meson.get_compiler('fortran') -cc = fc fc_id = fc.get_id() # Retrieve Fortran and C++ compiler objects fortran_compiler = meson.get_compiler('fortran') -cxx_compiler = meson.get_compiler('cpp') # Find dependencies: BLAS, LAPACK, OpenMP -# blas_dep = dependency('openblas', required: true) -# lapack_dep = dependency('lapack', required: true) - lapack_vendor = get_option('lapack') if lapack_vendor == 'auto' - if fc_id == 'intel' - lapack_vendor = 'mkl' - endif + if fc_id == 'intel' + lapack_vendor = 'mkl' + endif endif lib_deps = [] if lapack_vendor == 'mkl' - mkl_dep = [] - if fc_id == 'intel' - mkl_dep += cc.find_library('mkl_intel_lp64') - if get_option('openmp') - mkl_dep += cc.find_library('mkl_intel_thread') - endif - elif fc_id == 'gcc' - mkl_dep += cc.find_library('mkl_gf_lp64') - if get_option('openmp') - mkl_dep += cc.find_library('mkl_gnu_thread') - endif - else - error('MKL not supported for this compiler') - endif - if not get_option('openmp') - mkl_dep += cc.find_library('mkl_tbb_thread') - endif - mkl_dep += cc.find_library('mkl_core') - lib_deps += mkl_dep - add_project_arguments(['-DWITH_MKL'], language: 'fortran') + mkl_dep = [] + if fc_id == 'intel' + mkl_dep += fc.find_library('mkl_intel_lp64') + if get_option('openmp') + mkl_dep += fc.find_library('mkl_intel_thread') + endif + elif fc_id == 'gcc' + mkl_dep += fc.find_library('mkl_gf_lp64') + if get_option('openmp') + mkl_dep += fc.find_library('mkl_gnu_thread') + endif + else + error('MKL not supported for this compiler') + endif + if not get_option('openmp') + mkl_dep += fc.find_library('mkl_tbb_thread') + endif + mkl_dep += fc.find_library('mkl_core') + lib_deps += mkl_dep + add_project_arguments(['-DWITH_MKL'], language: 'fortran') elif lapack_vendor == 'mkl-rt' - mkl_dep = cc.find_library('mkl_rt') - lib_deps += mkl_dep - add_project_arguments(['-DWITH_MKL'], language: 'fortran') + mkl_dep = fc.find_library('mkl_rt') + lib_deps += mkl_dep + add_project_arguments(['-DWITH_MKL'], language: 'fortran') elif lapack_vendor == 'openblas' - blas_dep = dependency('openblas', required: false) - if not blas_dep.found() - blas_dep = cc.find_library('openblas') - endif - lib_deps += blas_dep - if not fc.links('external dsytrs; call dsytrs(); end', dependencies: blas_dep) - lapack_dep = dependency('lapack', required: false) - if not lapack_dep.found() - lapack_dep = cc.find_library('lapack') - endif - lib_deps += lapack_dep - endif - + blas_dep = dependency('openblas', required: false) + if not blas_dep.found() + blas_dep = fc.find_library('openblas') + endif + lib_deps += blas_dep + if not fc.links('external dsytrs; call dsytrs(); end', dependencies: blas_dep) + lapack_dep = dependency('lapack', required: false) + if not lapack_dep.found() + lapack_dep = fc.find_library('lapack') + endif + lib_deps += lapack_dep + endif elif lapack_vendor == 'custom' - foreach lib: get_option('custom_libraries') - lib_deps += cc.find_library(lib) - endforeach - + foreach lib: get_option('custom_libraries') + lib_deps += fc.find_library(lib) + endforeach else - lapack_dep = dependency('lapack', required: false) - if not lapack_dep.found() - lapack_dep = cc.find_library('lapack') - endif - lib_deps += lapack_dep - blas_dep = dependency('blas', required: false) - if not blas_dep.found() - blas_dep = cc.find_library('blas') - endif - lib_deps += blas_dep + lapack_dep = dependency('lapack', required: false) + if not lapack_dep.found() + lapack_dep = fc.find_library('lapack') + endif + lib_deps += lapack_dep + blas_dep = dependency('blas', required: false) + if not blas_dep.found() + blas_dep = fc.find_library('blas') + endif + lib_deps += blas_dep endif -openmp_dep = dependency('openmp', required: true) -lib_deps += openmp_dep - - -# dependency('openblas', required: false) +openmp_dep = dependency('openmp', required: get_option('openmp')) +if openmp_dep.found() + lib_deps += openmp_dep +endif subdir('config') -# Create a ddX library +# Create the ddX library ddx_library = library( - 'ddX', - sources: [ - 'src/ddx.f90', - 'src/cbessel.f90', - 'src/ddx_driver.f90', - 'src/ddx_lpb_core.f90', - 'src/ddx_workspace.f90', - 'src/ddx_errors.f90', - 'src/ddx_lpb.f90', - 'src/llgnew.f', - 'src/ddx_cinterface.f90', - 'src/ddx_multipolar_solutes.f90', - 'src/ddx_constants.f90', - 'src/ddx_gradients.f90', - 'src/ddx_operators.f90', - 'src/ddx_core.f90', - 'src/ddx_parameters.f90', - 'src/ddx_cosmo.f90', - 'src/ddx_harmonics.f90', - 'src/ddx_pcm.f90', - 'src/ddx_definitions.f90', - 'src/ddx_legacy.f90', - 'src/ddx_solvers.f90' - ], - dependencies: lib_deps + 'ddX', + sources: [ + 'src/ddx.f90', + 'src/cbessel.f90', + 'src/ddx_driver.f90', + 'src/ddx_lpb_core.f90', + 'src/ddx_workspace.f90', + 'src/ddx_errors.f90', + 'src/ddx_lpb.f90', + 'src/llgnew.f', + 'src/ddx_cinterface.f90', + 'src/ddx_multipolar_solutes.f90', + 'src/ddx_constants.f90', + 'src/ddx_gradients.f90', + 'src/ddx_operators.f90', + 'src/ddx_core.f90', + 'src/ddx_parameters.f90', + 'src/ddx_cosmo.f90', + 'src/ddx_harmonics.f90', + 'src/ddx_pcm.f90', + 'src/ddx_definitions.f90', + 'src/ddx_legacy.f90', + 'src/ddx_solvers.f90' + ], + dependencies: lib_deps ) # Export dependency for other projects and test suite @@ -131,11 +122,14 @@ ddx_dep = declare_dependency(link_with: ddx_library) # Add executable target for ddX (if needed) executable_target = executable( - 'ddX_exec', - sources: ['src/ddx_driver.f90'], - link_with: [ddx_library, ], - dependencies: lib_deps + 'ddX_exec', + sources: ['src/ddx_driver.f90'], + link_with: [ddx_library, ], + dependencies: lib_deps ) -# add the testsuite -subdir('tests') \ No newline at end of file +# Add the testsuite +subdir('tests') + +# Add the standalone tests +subdir('tests/standalone_tests') \ No newline at end of file diff --git a/meson_options.txt b/meson_options.txt index 96911885..ef84caf8 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -15,33 +15,26 @@ # along with tblite. If not, see . option( - 'lapack', - type: 'combo', - value: 'auto', - yield: true, - choices: ['auto', 'mkl', 'mkl-rt', 'openblas', 'netlib', 'custom'], - description : 'linear algebra backend', + 'lapack', + type: 'combo', + value: 'auto', + yield: true, + choices: ['auto', 'mkl', 'mkl-rt', 'openblas', 'netlib', 'custom'], + description : 'linear algebra backend', ) option( - 'custom_libraries', - type: 'array', - value: [], - yield: true, - description: 'libraries to load for custom linear algebra backend', + 'custom_libraries', + type: 'array', + value: [], + yield: true, + description: 'libraries to load for custom linear algebra backend', ) option( - 'openmp', - type: 'boolean', - value: true, - yield: true, - description: 'use OpenMP parallelisation', -) - -option( - 'api', - type: 'boolean', - value: true, - description: 'Build C API using iso_c_binding module', -) + 'openmp', + type: 'boolean', + value: true, + yield: true, + description: 'use OpenMP parallelisation', +) \ No newline at end of file diff --git a/tests/meson.build b/tests/meson.build index 1b462b5f..4892c3d8 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,56 +1,58 @@ project_dir = meson.current_source_dir() -# Test sources with their arguments # Test sources with their arguments test_sources = [ - ['ddx_core.f90', []], - ['ddx_operators.f90', []], - ['bessel.f90', []], - ['ddx_driver.f90', [ - join_paths(project_dir, 'data/ddpcm_force_fmm.in') + ' ' + join_paths(project_dir, 'data/ddpcm_force_fmm.out') + ' 1E-12', - join_paths(project_dir, 'data/ddcosmo_force_fmm.in') + ' ' + join_paths(project_dir, 'data/ddcosmo_force_fmm.out') + ' 1E-12' - ]], - ['force_ddlpb.f90', [join_paths(project_dir, 'data/ddlpb_force.txt')]], - ['ddlpb_esolv.f90', [join_paths(project_dir, 'data/ddlpb_force.txt')]], - ['matrix_derivatives.f90', [join_paths(project_dir, 'data/ddlpb_force.txt')]], - ['matrix_adjoint.f90', [join_paths(project_dir, 'data/ddlpb_force.txt')]], - ['matrix_solvers.f90', [join_paths(project_dir, 'data/ddlpb_force.txt')]], - ['m2l.f90', []], - ['multipolar_solutes.f90', []], - ['error.f90', []] + ['ddx_core.f90', []], + ['ddx_operators.f90', []], + ['bessel.f90', []], + ['force.f90', [join_paths(project_dir, 'Input_force.txt')]], + ['ddx_driver.f90', [ + join_paths(project_dir, 'data/ddpcm_force_fmm.in') + ' ' + join_paths(project_dir, 'data/ddpcm_force_fmm.out') + ' 1E-12', + join_paths(project_dir, 'data/ddcosmo_force_fmm.in') + ' ' + join_paths(project_dir, 'data/ddcosmo_force_fmm.out') + ' 1E-12' + ]], + ['force_ddlpb.f90', [join_paths(project_dir, 'data/ddlpb_force.txt')]], + ['ddlpb_esolv.f90', [join_paths(project_dir, 'data/ddlpb_force.txt')]], + ['matrix_derivatives.f90', [join_paths(project_dir, 'data/ddlpb_force.txt')]], + ['matrix_adjoint.f90', [join_paths(project_dir, 'data/ddlpb_force.txt')]], + ['matrix_solvers.f90', [join_paths(project_dir, 'data/ddlpb_force.txt')]], + ['m2l.f90', []], + ['multipolar_solutes.f90', []], + ['error.f90', []] ] # Create test executables and add tests foreach source_entry : test_sources - src = source_entry[0] - args = source_entry[1] - executable_name = src.split('.')[0] + src = source_entry[0] + args = source_entry[1] + executable_name = src.split('.')[0] - test_executable = executable( - executable_name, - src, - dependencies: [blas_dep, lapack_dep, openmp_dep, ddx_dep], # Link to ddx_dep - install: false + test_executable = executable( + executable_name, + src, + dependencies: [blas_dep, lapack_dep, openmp_dep, ddx_dep], # Link to ddx_dep + install: false ) - # Add the test with ddX runtime dependency - if args.length() == 0 - test(executable_name, test_executable) - else - idx = 0 - foreach arg_set : args - test( - executable_name + '_' + idx.to_string(), - test_executable, - args: arg_set.split(), - timeout: 240 - ) + # If the executable is ddx_driver, store it for the extra test + if executable_name == 'ddx_driver' + ddx_driver_exe = test_executable + endif - # print out the exact command with argument for each test - message('test ' + idx.to_string() + ' ' + executable_name + ' ' + arg_set) + if args.length() == 0 + test(executable_name, test_executable) + else + idx = 0 + foreach arg_set : args + test( + executable_name + '_' + idx.to_string(), + test_executable, + args: arg_set.split(), + timeout: 240 + ) + message('test ' + idx.to_string() + ' ' + executable_name + ' ' + arg_set) + idx += 1 + endforeach + endif +endforeach - idx += 1 - endforeach - endif -endforeach \ No newline at end of file diff --git a/tests/standalone_tests/meson.build b/tests/standalone_tests/meson.build new file mode 100644 index 00000000..071628f7 --- /dev/null +++ b/tests/standalone_tests/meson.build @@ -0,0 +1,62 @@ +# Build ddx_driver_testing (if needed) +ddx_driver_testing_exe = executable( + 'ddx_driver_testing', + 'ddx_driver_testing.f90', + dependencies: [ + ddx_dep, # your ddX library dependency + openmp_dep # OpenMP dependency + ], # or whatever Fortran deps you have + include_directories: include_directories('.'), + install: false +) + +# Copy run_test.py to the build directory +# (If run_test.py already has +x permission, this copy should preserve it on most OS.) +configure_file( + input: 'run_test.py', + output: 'run_test.py', + copy: true +) + +# Define a list of test basenames. +standalone_tests = [ + 'cosmo', + 'cosmo_fmm', + 'cosmo_incore', + 'pcm', + 'pcm_fmm', + 'pcm_incore', + 'lpb', + 'lpb_fmm', + 'lpb_incore' +] + +foreach t : standalone_tests + # Copy each test’s .txt and .ref files into the build dir. + configure_file( + input: t + '.txt', + output: t + '.txt', + copy: true + ) + configure_file( + input: t + '.ref', + output: t + '.ref', + copy: true + ) + + # Generate a small shell wrapper from meson_test_wrapper.in + # We replace the placeholders with the actual test name and build directory. + meson_test_wrapper = configure_file( + input: 'meson_test_wrapper.in', + output: t + '_wrapper.sh', + configuration: { + 'BUILD_DIR': meson.project_build_root(), + 'TESTNAME': t + }, + copy: false + ) + + # Finally, register the wrapper script as a test with Meson. + # This call has exactly two arguments: the test name, and the wrapper "File". + test(t, meson_test_wrapper) +endforeach diff --git a/tests/standalone_tests/meson_test_wrapper.in b/tests/standalone_tests/meson_test_wrapper.in new file mode 100755 index 00000000..075e72b5 --- /dev/null +++ b/tests/standalone_tests/meson_test_wrapper.in @@ -0,0 +1,7 @@ +#!/bin/sh +# We do NOT rely on run_test.py being executable. +# Instead, we call it via python3, which is typically in PATH. + +cd @BUILD_DIR@/tests/standalone_tests + +./run_test.py @TESTNAME@ \ No newline at end of file From 022b43896a4824e25b718c74b49f24b74d333dde Mon Sep 17 00:00:00 2001 From: lukaswittmann Date: Tue, 11 Mar 2025 14:09:25 +0100 Subject: [PATCH 06/15] Added meson build instructions and updated the download and install instructions --- docs/download_and_install.md | 84 ++++++++++++++++++++++++++++-------- 1 file changed, 65 insertions(+), 19 deletions(-) diff --git a/docs/download_and_install.md b/docs/download_and_install.md index bd279586..44dbbd3c 100644 --- a/docs/download_and_install.md +++ b/docs/download_and_install.md @@ -15,36 +15,60 @@ setup.py test ```
-## Source code -**Download the ddX source code** at: +## Source Code + +**Download the ddX source code** from GitHub: + ``` -git@github.com:ddsolvation/ddX.git +git clone git@github.com:ddsolvation/ddX.git ``` -**Download and install** ddX as follows: + +Then change into the cloned directory: + ``` -> git clone git@github.com:ddsolvation/ddX.git -> cd ddX -> mkdir build -> cd build -> cmake .. -> make +cd ddX ``` -Per default, the library is located in /src. + +The main Fortran sources for ddX reside in the `src/` folder. You can build ddX using either **CMake** or **Meson**, as outlined below. + +--- + +## Building with CMake + +1. Create a build directory and enter it: + ```bash + mkdir build + cd build + ``` +2. Run CMake to configure: + ```bash + cmake .. + ``` +3. Compile the library and executables: + ```bash + make + ``` +4. (Optional) Run the test suite: + ```bash + make test + ``` + +By default, the compiled library and executables will appear in the `build` folder. The original sources remain in `src/`. **Build the documentation** as follows (after you have done the above process): -``` -> cd build -> make docs +```bash +cd build +make docs ``` **To see the documentation** -``` -> cd ../doxygen -> pwd +```bash +cd ../doxygen +pwd ``` Copy the link shown by pwd and add /index.html in a web browser -#### Hints and hacks -1. For specifying compilers use + +**Specifying compilers** can be done by passing the desired compilers to CMake: ``` cmake -D CMAKE_CXX_COMPILER=/usr/local/bin/g++-11 CMAKE_Fortran_COMPILER=/usr/local/bin/gfortran-11 .. ``` @@ -53,3 +77,25 @@ or cmake -D CMAKE_CXX_COMPILER=icx CMAKE_Fortran_COMPILER=ifort .. ``` **NOTE**: Replace with the compilers you desire. + + +--- + +## Building with Meson + +1. Set up a build directory: + ```bash + meson setup build + ``` +2. Compile: + ```bash + meson compile -C build + ``` +3. Run the test suite (and print any error logs): + ```bash + meson test -C build + ``` + +Again, the built library and any executables will appear in the `build` folder, while the ddX source remains in `src/`. + + From 575c2e6b4efa31a8087d0016cee19777ac2778e1 Mon Sep 17 00:00:00 2001 From: lukaswittmann Date: Tue, 11 Mar 2025 14:26:33 +0100 Subject: [PATCH 07/15] Cleanup of --- .meson-subproject-wrap-hash.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .meson-subproject-wrap-hash.txt diff --git a/.meson-subproject-wrap-hash.txt b/.meson-subproject-wrap-hash.txt deleted file mode 100644 index 5fe03181..00000000 --- a/.meson-subproject-wrap-hash.txt +++ /dev/null @@ -1 +0,0 @@ -23c02f2dc3bd78c024608ca25c933304b62ede67384736d9eb8247e70e1ba05b From e7df9add4fb0c060ac681b83fb3103de43d1f5fc Mon Sep 17 00:00:00 2001 From: lukaswittmann Date: Tue, 11 Mar 2025 14:28:43 +0100 Subject: [PATCH 08/15] Added meson version number to download and install instructions --- docs/download_and_install.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/download_and_install.md b/docs/download_and_install.md index 44dbbd3c..bea6aef5 100644 --- a/docs/download_and_install.md +++ b/docs/download_and_install.md @@ -83,6 +83,9 @@ cmake -D CMAKE_CXX_COMPILER=icx CMAKE_Fortran_COMPILER=ifort .. ## Building with Meson +[meson](https://mesonbuild.com) version 0.61 or newer, with + a build-system backend, *i.e.* [ninja](https://ninja-build.org) version 1.10 or newer, are required. + 1. Set up a build directory: ```bash meson setup build From 2ad570610cd3a1d609dfa270c116d05c29256dec Mon Sep 17 00:00:00 2001 From: lukaswittmann Date: Tue, 11 Mar 2025 14:31:01 +0100 Subject: [PATCH 09/15] Cleaned up meson build files --- config/meson.build | 16 ---------------- meson_options.txt | 16 ---------------- tests/meson.build | 1 - 3 files changed, 33 deletions(-) diff --git a/config/meson.build b/config/meson.build index 4dd7aafc..7a3ca04d 100644 --- a/config/meson.build +++ b/config/meson.build @@ -1,19 +1,3 @@ -# This file is part of dftd4. -# SPDX-Identifier: LGPL-3.0-or-later -# -# dftd4 is free software: you can redistribute it and/or modify it under -# the terms of the Lesser GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# dftd4 is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# Lesser GNU General Public License for more details. -# -# You should have received a copy of the Lesser GNU General Public License -# along with dftd4. If not, see . - os = host_machine.system() fc = meson.get_compiler('fortran') cc = fc diff --git a/meson_options.txt b/meson_options.txt index ef84caf8..52253026 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,19 +1,3 @@ -# This file is part of tblite. -# SPDX-Identifier: LGPL-3.0-or-later -# -# tblite is free software: you can redistribute it and/or modify it under -# the terms of the Lesser GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# tblite is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# Lesser GNU General Public License for more details. -# -# You should have received a copy of the Lesser GNU General Public License -# along with tblite. If not, see . - option( 'lapack', type: 'combo', diff --git a/tests/meson.build b/tests/meson.build index 4892c3d8..a611d349 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,4 +1,3 @@ - project_dir = meson.current_source_dir() # Test sources with their arguments From a15e738f2251f0e067420a5fc8eb092994c3c877 Mon Sep 17 00:00:00 2001 From: lukaswittmann Date: Tue, 11 Mar 2025 14:35:54 +0100 Subject: [PATCH 10/15] Cleaned up the meson build file for the standalone tests. --- tests/standalone_tests/meson.build | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tests/standalone_tests/meson.build b/tests/standalone_tests/meson.build index 071628f7..33e2d0e8 100644 --- a/tests/standalone_tests/meson.build +++ b/tests/standalone_tests/meson.build @@ -1,15 +1,3 @@ -# Build ddx_driver_testing (if needed) -ddx_driver_testing_exe = executable( - 'ddx_driver_testing', - 'ddx_driver_testing.f90', - dependencies: [ - ddx_dep, # your ddX library dependency - openmp_dep # OpenMP dependency - ], # or whatever Fortran deps you have - include_directories: include_directories('.'), - install: false -) - # Copy run_test.py to the build directory # (If run_test.py already has +x permission, this copy should preserve it on most OS.) configure_file( From 876058f2f03179d0cfa9daa037e06dcdbd73f66a Mon Sep 17 00:00:00 2001 From: lukaswittmann Date: Mon, 24 Mar 2025 10:50:13 +0100 Subject: [PATCH 11/15] Fix for blas_dep. --- meson.build | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/meson.build b/meson.build index cdc4a4ff..1ab3a514 100644 --- a/meson.build +++ b/meson.build @@ -14,8 +14,8 @@ install = not (meson.is_subproject() and get_option('default_library') == 'stati fc = meson.get_compiler('fortran') fc_id = fc.get_id() -# Retrieve Fortran and C++ compiler objects -fortran_compiler = meson.get_compiler('fortran') +# Retrieve Fortran compiler object +fortran_compiler = fc # Find dependencies: BLAS, LAPACK, OpenMP lapack_vendor = get_option('lapack') @@ -44,13 +44,18 @@ if lapack_vendor == 'mkl' if not get_option('openmp') mkl_dep += fc.find_library('mkl_tbb_thread') endif - mkl_dep += fc.find_library('mkl_core') + # Ensure we add the MKL core library and assign it as blas_dep since it provides BLAS functionality. + mkl_core = fc.find_library('mkl_core') + mkl_dep += mkl_core lib_deps += mkl_dep add_project_arguments(['-DWITH_MKL'], language: 'fortran') + blas_dep = mkl_core elif lapack_vendor == 'mkl-rt' mkl_dep = fc.find_library('mkl_rt') lib_deps += mkl_dep add_project_arguments(['-DWITH_MKL'], language: 'fortran') + # In this case we assume mkl_rt also provides BLAS functionality: + blas_dep = mkl_dep elif lapack_vendor == 'openblas' blas_dep = dependency('openblas', required: false) if not blas_dep.found() @@ -68,6 +73,11 @@ elif lapack_vendor == 'custom' foreach lib: get_option('custom_libraries') lib_deps += fc.find_library(lib) endforeach + # Provide a blas_dep even for custom libraries + blas_dep = dependency('blas', required: false) + if not blas_dep.found() + blas_dep = fc.find_library('blas') + endif else lapack_dep = dependency('lapack', required: false) if not lapack_dep.found() @@ -124,7 +134,7 @@ ddx_dep = declare_dependency(link_with: ddx_library) executable_target = executable( 'ddX_exec', sources: ['src/ddx_driver.f90'], - link_with: [ddx_library, ], + link_with: [ddx_library], dependencies: lib_deps ) @@ -132,4 +142,4 @@ executable_target = executable( subdir('tests') # Add the standalone tests -subdir('tests/standalone_tests') \ No newline at end of file +subdir('tests/standalone_tests') From 23bdc8305aa4e2a91d53ece3af678ef953197311 Mon Sep 17 00:00:00 2001 From: lukaswittmann Date: Wed, 26 Mar 2025 14:37:30 +0100 Subject: [PATCH 12/15] Fix for lapack_dep. --- meson.build | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 1ab3a514..b3b97151 100644 --- a/meson.build +++ b/meson.build @@ -50,12 +50,21 @@ if lapack_vendor == 'mkl' lib_deps += mkl_dep add_project_arguments(['-DWITH_MKL'], language: 'fortran') blas_dep = mkl_core + # Define lapack_dep even though MKL supplies LAPACK functionality: + lapack_dep = dependency('lapack', required: false) + if not lapack_dep.found() + lapack_dep = fc.find_library('lapack') + endif elif lapack_vendor == 'mkl-rt' mkl_dep = fc.find_library('mkl_rt') lib_deps += mkl_dep add_project_arguments(['-DWITH_MKL'], language: 'fortran') - # In this case we assume mkl_rt also provides BLAS functionality: + # Assume mkl_rt provides both LAPACK and BLAS functionality: blas_dep = mkl_dep + lapack_dep = dependency('lapack', required: false) + if not lapack_dep.found() + lapack_dep = fc.find_library('lapack') + endif elif lapack_vendor == 'openblas' blas_dep = dependency('openblas', required: false) if not blas_dep.found() @@ -68,6 +77,12 @@ elif lapack_vendor == 'openblas' lapack_dep = fc.find_library('lapack') endif lib_deps += lapack_dep + else + # Even if the test passes the link check, define lapack_dep for consistency. + lapack_dep = dependency('lapack', required: false) + if not lapack_dep.found() + lapack_dep = fc.find_library('lapack') + endif endif elif lapack_vendor == 'custom' foreach lib: get_option('custom_libraries') @@ -78,6 +93,11 @@ elif lapack_vendor == 'custom' if not blas_dep.found() blas_dep = fc.find_library('blas') endif + # Also define lapack_dep for tests: + lapack_dep = dependency('lapack', required: false) + if not lapack_dep.found() + lapack_dep = fc.find_library('lapack') + endif else lapack_dep = dependency('lapack', required: false) if not lapack_dep.found() From 61c88ddb8b6dee393c6d93760075c50bc54bd0cd Mon Sep 17 00:00:00 2001 From: lukaswittmann Date: Wed, 26 Mar 2025 14:41:41 +0100 Subject: [PATCH 13/15] Fix for lapack. --- meson.build | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/meson.build b/meson.build index b3b97151..61d2806d 100644 --- a/meson.build +++ b/meson.build @@ -44,27 +44,20 @@ if lapack_vendor == 'mkl' if not get_option('openmp') mkl_dep += fc.find_library('mkl_tbb_thread') endif - # Ensure we add the MKL core library and assign it as blas_dep since it provides BLAS functionality. + # Add the MKL core library; MKL supplies LAPACK routines. mkl_core = fc.find_library('mkl_core') mkl_dep += mkl_core lib_deps += mkl_dep add_project_arguments(['-DWITH_MKL'], language: 'fortran') blas_dep = mkl_core - # Define lapack_dep even though MKL supplies LAPACK functionality: - lapack_dep = dependency('lapack', required: false) - if not lapack_dep.found() - lapack_dep = fc.find_library('lapack') - endif + # Instead of looking for a separate lapack library, create a dependency using MKL. + lapack_dep = declare_dependency(link_with: mkl_dep) elif lapack_vendor == 'mkl-rt' mkl_dep = fc.find_library('mkl_rt') lib_deps += mkl_dep add_project_arguments(['-DWITH_MKL'], language: 'fortran') - # Assume mkl_rt provides both LAPACK and BLAS functionality: blas_dep = mkl_dep - lapack_dep = dependency('lapack', required: false) - if not lapack_dep.found() - lapack_dep = fc.find_library('lapack') - endif + lapack_dep = declare_dependency(link_with: mkl_dep) elif lapack_vendor == 'openblas' blas_dep = dependency('openblas', required: false) if not blas_dep.found() @@ -78,7 +71,6 @@ elif lapack_vendor == 'openblas' endif lib_deps += lapack_dep else - # Even if the test passes the link check, define lapack_dep for consistency. lapack_dep = dependency('lapack', required: false) if not lapack_dep.found() lapack_dep = fc.find_library('lapack') @@ -88,12 +80,10 @@ elif lapack_vendor == 'custom' foreach lib: get_option('custom_libraries') lib_deps += fc.find_library(lib) endforeach - # Provide a blas_dep even for custom libraries blas_dep = dependency('blas', required: false) if not blas_dep.found() blas_dep = fc.find_library('blas') endif - # Also define lapack_dep for tests: lapack_dep = dependency('lapack', required: false) if not lapack_dep.found() lapack_dep = fc.find_library('lapack') From f3c78705b4769bf2a7785ee06e295a698532ceb6 Mon Sep 17 00:00:00 2001 From: lukaswittmann Date: Wed, 26 Mar 2025 14:58:22 +0100 Subject: [PATCH 14/15] Meson rework. --- meson.build | 225 +++++++++++++++++++++------------------------- tests/meson.build | 2 +- 2 files changed, 101 insertions(+), 126 deletions(-) diff --git a/meson.build b/meson.build index 61d2806d..8a49b344 100644 --- a/meson.build +++ b/meson.build @@ -1,155 +1,130 @@ -# Minimum version and project definition project('ddX', - 'fortran', - 'cpp', - version: '0.6.0', - license: 'LGPL-3.0-or-later', - default_options: [ - 'buildtype=debugoptimized', - 'default_library=both', - ], + 'fortran', + 'cpp', + version: '0.6.0', + license: 'LGPL-3.0-or-later', + meson_version: '>=0.57.2', + default_options: [ + 'default_library=both', + ], ) install = not (meson.is_subproject() and get_option('default_library') == 'static') fc = meson.get_compiler('fortran') fc_id = fc.get_id() - -# Retrieve Fortran compiler object fortran_compiler = fc -# Find dependencies: BLAS, LAPACK, OpenMP +lib_deps = [] +if get_option('openmp') + omp_dep = dependency('openmp') + lib_deps += omp_dep +endif + lapack_vendor = get_option('lapack') if lapack_vendor == 'auto' - if fc_id == 'intel' - lapack_vendor = 'mkl' - endif + if fc_id == 'intel' + lapack_vendor = 'mkl' + endif endif -lib_deps = [] if lapack_vendor == 'mkl' - mkl_dep = [] - if fc_id == 'intel' - mkl_dep += fc.find_library('mkl_intel_lp64') - if get_option('openmp') - mkl_dep += fc.find_library('mkl_intel_thread') - endif - elif fc_id == 'gcc' - mkl_dep += fc.find_library('mkl_gf_lp64') - if get_option('openmp') - mkl_dep += fc.find_library('mkl_gnu_thread') - endif - else - error('MKL not supported for this compiler') - endif - if not get_option('openmp') - mkl_dep += fc.find_library('mkl_tbb_thread') - endif - # Add the MKL core library; MKL supplies LAPACK routines. - mkl_core = fc.find_library('mkl_core') - mkl_dep += mkl_core - lib_deps += mkl_dep - add_project_arguments(['-DWITH_MKL'], language: 'fortran') - blas_dep = mkl_core - # Instead of looking for a separate lapack library, create a dependency using MKL. - lapack_dep = declare_dependency(link_with: mkl_dep) + mkl_dep = [] + if fc_id == 'intel' + mkl_dep += cc.find_library('mkl_intel_lp64') + if get_option('openmp') + mkl_dep += cc.find_library('mkl_intel_thread') + endif + elif fc_id == 'gcc' + mkl_dep += cc.find_library('mkl_gf_lp64') + if get_option('openmp') + mkl_dep += cc.find_library('mkl_gnu_thread') + endif + else + error('MKL not supported for this compiler') + endif + if not get_option('openmp') + mkl_dep += cc.find_library('mkl_tbb_thread') + endif + mkl_dep += cc.find_library('mkl_core') + lib_deps += mkl_dep + add_project_arguments(['-DWITH_MKL'], language: 'fortran') elif lapack_vendor == 'mkl-rt' - mkl_dep = fc.find_library('mkl_rt') - lib_deps += mkl_dep - add_project_arguments(['-DWITH_MKL'], language: 'fortran') - blas_dep = mkl_dep - lapack_dep = declare_dependency(link_with: mkl_dep) + mkl_dep = cc.find_library('mkl_rt') + lib_deps += mkl_dep + add_project_arguments(['-DWITH_MKL'], language: 'fortran') elif lapack_vendor == 'openblas' - blas_dep = dependency('openblas', required: false) - if not blas_dep.found() - blas_dep = fc.find_library('openblas') - endif - lib_deps += blas_dep - if not fc.links('external dsytrs; call dsytrs(); end', dependencies: blas_dep) - lapack_dep = dependency('lapack', required: false) - if not lapack_dep.found() - lapack_dep = fc.find_library('lapack') - endif - lib_deps += lapack_dep - else - lapack_dep = dependency('lapack', required: false) - if not lapack_dep.found() - lapack_dep = fc.find_library('lapack') - endif - endif + openblas_dep = dependency('openblas', required: false) + if not openblas_dep.found() + openblas_dep = cc.find_library('openblas') + endif + lib_deps += openblas_dep + if not fc.links('external dsytrs; call dsytrs(); end', dependencies: openblas_dep) + lapack_dep = dependency('lapack', required: false) + if not lapack_dep.found() + lapack_dep = cc.find_library('lapack') + endif + lib_deps += lapack_dep + endif + elif lapack_vendor == 'custom' - foreach lib: get_option('custom_libraries') - lib_deps += fc.find_library(lib) - endforeach - blas_dep = dependency('blas', required: false) - if not blas_dep.found() - blas_dep = fc.find_library('blas') - endif - lapack_dep = dependency('lapack', required: false) - if not lapack_dep.found() - lapack_dep = fc.find_library('lapack') - endif -else - lapack_dep = dependency('lapack', required: false) - if not lapack_dep.found() - lapack_dep = fc.find_library('lapack') - endif - lib_deps += lapack_dep - blas_dep = dependency('blas', required: false) - if not blas_dep.found() - blas_dep = fc.find_library('blas') - endif - lib_deps += blas_dep -endif + foreach lib: get_option('custom_libraries') + lib_deps += cc.find_library(lib) + endforeach -openmp_dep = dependency('openmp', required: get_option('openmp')) -if openmp_dep.found() - lib_deps += openmp_dep +else + lapack_dep = dependency('lapack', required: false) + if not lapack_dep.found() + lapack_dep = cc.find_library('lapack') + endif + lib_deps += lapack_dep + blas_dep = dependency('blas', required: false) + if not blas_dep.found() + blas_dep = cc.find_library('blas') + endif + lib_deps += blas_dep endif subdir('config') -# Create the ddX library ddx_library = library( - 'ddX', - sources: [ - 'src/ddx.f90', - 'src/cbessel.f90', - 'src/ddx_driver.f90', - 'src/ddx_lpb_core.f90', - 'src/ddx_workspace.f90', - 'src/ddx_errors.f90', - 'src/ddx_lpb.f90', - 'src/llgnew.f', - 'src/ddx_cinterface.f90', - 'src/ddx_multipolar_solutes.f90', - 'src/ddx_constants.f90', - 'src/ddx_gradients.f90', - 'src/ddx_operators.f90', - 'src/ddx_core.f90', - 'src/ddx_parameters.f90', - 'src/ddx_cosmo.f90', - 'src/ddx_harmonics.f90', - 'src/ddx_pcm.f90', - 'src/ddx_definitions.f90', - 'src/ddx_legacy.f90', - 'src/ddx_solvers.f90' - ], - dependencies: lib_deps + 'ddX', + sources: [ + 'src/ddx.f90', + 'src/cbessel.f90', + 'src/ddx_driver.f90', + 'src/ddx_lpb_core.f90', + 'src/ddx_workspace.f90', + 'src/ddx_errors.f90', + 'src/ddx_lpb.f90', + 'src/llgnew.f', + 'src/ddx_cinterface.f90', + 'src/ddx_multipolar_solutes.f90', + 'src/ddx_constants.f90', + 'src/ddx_gradients.f90', + 'src/ddx_operators.f90', + 'src/ddx_core.f90', + 'src/ddx_parameters.f90', + 'src/ddx_cosmo.f90', + 'src/ddx_harmonics.f90', + 'src/ddx_pcm.f90', + 'src/ddx_definitions.f90', + 'src/ddx_legacy.f90', + 'src/ddx_solvers.f90' + ], + dependencies: lib_deps ) -# Export dependency for other projects and test suite -ddx_dep = declare_dependency(link_with: ddx_library) +ddx_dep = declare_dependency( + link_with: ddx_library, + dependencies: lib_deps +) -# Add executable target for ddX (if needed) executable_target = executable( - 'ddX_exec', - sources: ['src/ddx_driver.f90'], - link_with: [ddx_library], - dependencies: lib_deps + 'ddX_exec', + sources: ['src/ddx_driver.f90'], + link_with: [ddx_library], + dependencies: lib_deps ) -# Add the testsuite subdir('tests') - -# Add the standalone tests subdir('tests/standalone_tests') diff --git a/tests/meson.build b/tests/meson.build index a611d349..6be98ae4 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -29,7 +29,7 @@ foreach source_entry : test_sources test_executable = executable( executable_name, src, - dependencies: [blas_dep, lapack_dep, openmp_dep, ddx_dep], # Link to ddx_dep + dependencies: [lib_deps, ddx_dep], # Link to ddx_dep install: false ) From affec0e67c9b22a44dcfb3e08ca77786fafa7c47 Mon Sep 17 00:00:00 2001 From: lukaswittmann Date: Wed, 26 Mar 2025 15:01:10 +0100 Subject: [PATCH 15/15] cc to fc. --- meson.build | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/meson.build b/meson.build index 8a49b344..f8926aca 100644 --- a/meson.build +++ b/meson.build @@ -30,56 +30,56 @@ endif if lapack_vendor == 'mkl' mkl_dep = [] if fc_id == 'intel' - mkl_dep += cc.find_library('mkl_intel_lp64') + mkl_dep += fc.find_library('mkl_intel_lp64') if get_option('openmp') - mkl_dep += cc.find_library('mkl_intel_thread') + mkl_dep += fc.find_library('mkl_intel_thread') endif elif fc_id == 'gcc' - mkl_dep += cc.find_library('mkl_gf_lp64') + mkl_dep += fc.find_library('mkl_gf_lp64') if get_option('openmp') - mkl_dep += cc.find_library('mkl_gnu_thread') + mkl_dep += fc.find_library('mkl_gnu_thread') endif else error('MKL not supported for this compiler') endif if not get_option('openmp') - mkl_dep += cc.find_library('mkl_tbb_thread') + mkl_dep += fc.find_library('mkl_tbb_thread') endif - mkl_dep += cc.find_library('mkl_core') + mkl_dep += fc.find_library('mkl_core') lib_deps += mkl_dep add_project_arguments(['-DWITH_MKL'], language: 'fortran') elif lapack_vendor == 'mkl-rt' - mkl_dep = cc.find_library('mkl_rt') + mkl_dep = fc.find_library('mkl_rt') lib_deps += mkl_dep add_project_arguments(['-DWITH_MKL'], language: 'fortran') elif lapack_vendor == 'openblas' openblas_dep = dependency('openblas', required: false) if not openblas_dep.found() - openblas_dep = cc.find_library('openblas') + openblas_dep = fc.find_library('openblas') endif lib_deps += openblas_dep if not fc.links('external dsytrs; call dsytrs(); end', dependencies: openblas_dep) lapack_dep = dependency('lapack', required: false) if not lapack_dep.found() - lapack_dep = cc.find_library('lapack') + lapack_dep = fc.find_library('lapack') endif lib_deps += lapack_dep endif elif lapack_vendor == 'custom' foreach lib: get_option('custom_libraries') - lib_deps += cc.find_library(lib) + lib_deps += fc.find_library(lib) endforeach else lapack_dep = dependency('lapack', required: false) if not lapack_dep.found() - lapack_dep = cc.find_library('lapack') + lapack_dep = fc.find_library('lapack') endif lib_deps += lapack_dep blas_dep = dependency('blas', required: false) if not blas_dep.found() - blas_dep = cc.find_library('blas') + blas_dep = fc.find_library('blas') endif lib_deps += blas_dep endif