Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Commits on Source (4)
......@@ -74,6 +74,7 @@ find_package( PystencilsSfg )
Make sure to set the `Python_ROOT_DIR` cache variable to point to the correct Python interpreter
(i.e. the virtual environment you have installed *pystencils-sfg* into).
(cmake_add_generator_scripts)=
### Add generator scripts
The primary interaction point in CMake is the function `pystencilssfg_generate_target_sources`,
......@@ -85,6 +86,7 @@ pystencilssfg_generate_target_sources( <target>
[DEPENDS dependency1.py [dependency2.py...]]
[FILE_EXTENSIONS <header-extension> <impl-extension>]
[OUTPUT_MODE <standalone|inline|header-only>]
[CONFIG_MODULE <path-to-config-module.py>]
)
```
......@@ -97,6 +99,9 @@ The function takes the following options:
- `DEPENDS`: A list of dependencies for the generator scripts
- `FILE_EXTENSION`: The desired extensions for the generated files
- `OUTPUT_MODE`: Sets the output mode of the code generator; see {any}`SfgConfig.output_mode`.
- `CONFIG_MODULE`: Set the configuration module for all scripts registered with this call.
If set, this overrides the value of `PystencilsSfg_CONFIG_MODULE`
in the current scope (see [](#cmake_set_config_module))
### Include generated files
......@@ -110,9 +115,13 @@ path, such that generated header files for a target `<target>` may be included v
(cmake_set_config_module)=
### Set a Configuration Module
To specify a [configuration module](#config_module) for your project,
set the scoped variable `PystencilsSfg_CONFIG_MODULE` to point at the respective Python file.
The pystencils-sfg CMake system will then pass that module to each generator script invocation.
There are two ways of specifying a [configuration module](#config_module) for generator scripts
registered with CMake:
- To set a configuration module for scripts registered with a single call to `pystencilssfg_generate_target_sources`,
use the `CONFIG_MODULE` function parameter (see [](#cmake_add_generator_scripts)).
- To set a config module for all generator scripts within the current CMake directory and its subdirectories,
set the scoped variable `PystencilsSfg_CONFIG_MODULE` to point at the respective Python file, e.g.
`set( PystencilsSfg_CONFIG_MODULE ProjectConfig.py )`.
You might want to populate your configuration module with information about the current
build setup and environment.
......
from pystencils import Target, CreateKernelConfig, create_kernel, no_jit
from pystencils import Target, CreateKernelConfig, no_jit
from lbmpy import create_lb_update_rule, LBMOptimisation
from pystencilssfg import SourceFileGenerator, SfgConfiguration
from pystencilssfg.lang.cpp import mdspan_ref
from pystencilssfg import SourceFileGenerator, SfgConfig
sfg_config = SfgConfiguration(
output_directory="out/test_cuda",
outer_namespace="gen_code",
impl_extension="cu"
)
sfg_config = SfgConfig()
sfg_config.extensions.impl = "cu"
sfg_config.output_directory = "out/test_cuda"
sfg_config.outer_namespace = "gen_code"
with SourceFileGenerator(sfg_config) as sfg:
gen_config = CreateKernelConfig(target=Target.CUDA, jit=no_jit)
......@@ -15,6 +13,4 @@ with SourceFileGenerator(sfg_config) as sfg:
update = create_lb_update_rule()
kernel = sfg.kernels.create(update, "lbm_update", gen_config)
sfg.function("lb_update")(
sfg.call(kernel)
)
sfg.function("lb_update")(sfg.call(kernel))
......@@ -3,3 +3,6 @@ python_version=3.10
[mypy-pystencils.*]
ignore_missing_imports=true
[mypy-sympy.*]
ignore_missing_imports=true
......@@ -9,7 +9,7 @@ dependencies = [
]
requires-python = ">=3.10"
readme = "README.md"
license = { file = "COPYING.txt" }
license = { file = "LICENSE" }
dynamic = ["version"]
[project.scripts]
......
......@@ -9,5 +9,6 @@ addopts =
--ignore=tests/generator_scripts/deps
--ignore=tests/generator_scripts/expected
--ignore=tests/data
--ignore=tests/integration/cmake_project
doctest_optionflags = NORMALIZE_WHITESPACE IGNORE_EXCEPTION_DETAIL
......@@ -43,7 +43,7 @@ endfunction()
function(pystencilssfg_generate_target_sources TARGET)
set(options)
set(oneValueArgs OUTPUT_MODE)
set(oneValueArgs OUTPUT_MODE CONFIG_MODULE)
set(multiValueArgs SCRIPTS DEPENDS FILE_EXTENSIONS)
cmake_parse_arguments(_pssfg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
......@@ -53,21 +53,27 @@ function(pystencilssfg_generate_target_sources TARGET)
list(APPEND generatorArgs "--sfg-output-mode=${_pssfg_OUTPUT_MODE}")
endif()
if(DEFINED PystencilsSfg_CONFIGURATOR_SCRIPT)
message(AUTHOR_WARNING "The variable PystencilsSfg_CONFIGURATOR_SCRIPT is deprecated. Set PystencilsSfg_CONFIG_MODULE instead.")
cmake_path(ABSOLUTE_PATH PystencilsSfg_CONFIGURATOR_SCRIPT OUTPUT_VARIABLE configscript)
list(APPEND generatorArgs "--sfg-config-module=${configscript}")
list(APPEND _pssfg_DEPENDS ${configscript})
endif()
if(DEFINED PystencilsSfg_CONFIG_MODULE)
if(DEFINED _pssfg_CONFIG_MODULE)
cmake_path(ABSOLUTE_PATH _pssfg_CONFIG_MODULE OUTPUT_VARIABLE config_module)
list(APPEND generatorArgs "--sfg-config-module=${config_module}")
list(APPEND _pssfg_DEPENDS ${config_module})
else()
if(DEFINED PystencilsSfg_CONFIGURATOR_SCRIPT)
message(FATAL_ERROR "At most one of PystencilsSfg_CONFIGURATOR_SCRIPT and PystencilsSfg_CONFIG_MODULE may be set.")
message(AUTHOR_WARNING "The variable PystencilsSfg_CONFIGURATOR_SCRIPT is deprecated. Set PystencilsSfg_CONFIG_MODULE instead.")
cmake_path(ABSOLUTE_PATH PystencilsSfg_CONFIGURATOR_SCRIPT OUTPUT_VARIABLE configscript)
list(APPEND generatorArgs "--sfg-config-module=${configscript}")
list(APPEND _pssfg_DEPENDS ${configscript})
endif()
cmake_path(ABSOLUTE_PATH PystencilsSfg_CONFIG_MODULE OUTPUT_VARIABLE config_module)
list(APPEND generatorArgs "--sfg-config-module=${config_module}")
list(APPEND _pssfg_DEPENDS ${config_module})
if(DEFINED PystencilsSfg_CONFIG_MODULE)
if(DEFINED PystencilsSfg_CONFIGURATOR_SCRIPT)
message(FATAL_ERROR "At most one of PystencilsSfg_CONFIGURATOR_SCRIPT and PystencilsSfg_CONFIG_MODULE may be set.")
endif()
cmake_path(ABSOLUTE_PATH PystencilsSfg_CONFIG_MODULE OUTPUT_VARIABLE config_module)
list(APPEND generatorArgs "--sfg-config-module=${config_module}")
list(APPEND _pssfg_DEPENDS ${config_module})
endif()
endif()
if(DEFINED _pssfg_FILE_EXTENSIONS)
......
......@@ -24,6 +24,9 @@ class HeaderFile:
return header
system_header = False
if header.startswith('"') and header.endswith('"'):
header = header[1:-1]
if header.startswith("<") and header.endswith(">"):
header = header[1:-1]
system_header = True
......
FindPystencilsSfg.cmake
\ No newline at end of file
cmake_minimum_required( VERSION 3.22 )
project( sfg_cmake_project_test )
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
find_package( PystencilsSfg REQUIRED )
set( UseGlobalCfgModule OFF CACHE BOOL "Specify config module globally" )
set( UseLocalCfgModule OFF CACHE BOOL "Specify config module locally" )
if( $CACHE{UseGlobalCfgModule} )
set( PystencilsSfg_CONFIG_MODULE ${CMAKE_CURRENT_SOURCE_DIR}/gen_config.py )
endif()
add_executable( TestApp TestApp.cpp )
if( $CACHE{UseLocalCfgModule} )
pystencilssfg_generate_target_sources(
TestApp
SCRIPTS GenTest.py
CONFIG_MODULE ${CMAKE_CURRENT_SOURCE_DIR}/gen_config.py
)
else()
pystencilssfg_generate_target_sources(
TestApp
SCRIPTS GenTest.py
)
endif()
from pystencilssfg import SourceFileGenerator
with SourceFileGenerator() as sfg:
sfg.namespace("gen")
retval = 42 if sfg.context.project_info is None else sfg.context.project_info
sfg.function("getValue", return_type="int")(
f"return {retval};"
)
#include "gen/TestApp/GenTest.hpp"
int main(void) {
return int( gen::getValue() );
}
from pystencilssfg import SfgConfig
def configure_sfg(cfg: SfgConfig):
cfg.extensions.impl = "c++"
def project_info():
return 31
import pytest
import pathlib
import subprocess
THIS_DIR = pathlib.Path(__file__).parent
CMAKE_PROJECT_DIRNAME = "cmake_project"
CMAKE_PROJECT_DIR = THIS_DIR / CMAKE_PROJECT_DIRNAME
@pytest.mark.parametrize("config_source", [None, "UseGlobalCfgModule", "UseLocalCfgModule"])
def test_cmake_project(tmp_path, config_source):
obtain_find_module_cmd = ["sfg-cli", "cmake", "make-find-module"]
result = subprocess.run(obtain_find_module_cmd, cwd=CMAKE_PROJECT_DIR)
assert result.returncode == 0
cmake_configure_cmd = ["cmake", "-S", CMAKE_PROJECT_DIR, "-B", str(tmp_path)]
if config_source is not None:
cmake_configure_cmd.append(f"-D{config_source}=ON")
configure_result = subprocess.run(cmake_configure_cmd)
assert configure_result.returncode == 0
cmake_build_cmd = ["cmake", "--build", str(tmp_path), "--target", "TestApp"]
build_result = subprocess.run(cmake_build_cmd)
assert build_result.returncode == 0
run_cmd = [str(tmp_path / "TestApp")]
run_result = subprocess.run(run_cmd)
if config_source is not None:
assert (tmp_path / "sfg_sources" / "gen" / "TestApp" / "GenTest.c++").exists()
assert run_result.returncode == 31
else:
assert (tmp_path / "sfg_sources" / "gen" / "TestApp" / "GenTest.cpp").exists()
assert run_result.returncode == 42
from pystencilssfg.lang import HeaderFile
import pytest
def test_parse_system():
headerfile = HeaderFile.parse("<test>")
assert str(headerfile) == "<test>" and headerfile.system_header
@pytest.mark.parametrize("header_string", ["test.hpp", '"test.hpp"'])
def test_parse_private(header_string):
headerfile = HeaderFile.parse(header_string)
assert str(headerfile) == "test.hpp" and not headerfile.system_header