diff --git a/.gitignore b/.gitignore index 399dabec684a263e78c3fad0521f84f3807e5185..2d7f34cea4100f7d12b45e9c108edeeed8362fc5 100644 --- a/.gitignore +++ b/.gitignore @@ -18,9 +18,6 @@ dist *.egg-info # tests and coverage -.coverage +.coverage* htmlcov coverage.xml - -# mkdocs -site diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5331eca41f6a1ef142a74f923f3a79007e18d025..a89284abf85cf76c9af147b477e958b61e5bc96e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,9 +37,9 @@ testsuite: - docker before_script: - pip install "git+https://i10git.cs.fau.de/pycodegen/pystencils.git@v2.0-dev" - - pip install -e . + - pip install -e .[tests] script: - - pytest -v --cov=src/pystencilssfg --cov-report=term + - pytest -v --cov=src/pystencilssfg --cov-report=term --cov-config=pyproject.toml - coverage html - coverage xml coverage: '/TOTAL.*\s+(\d+%)$/' diff --git a/docs/source/index.md b/docs/source/index.md index 4e93f0ce207f948be923a24d7943892bf4a48f7f..ca35b36efb434430b4155a292784a092620db8d5 100644 --- a/docs/source/index.md +++ b/docs/source/index.md @@ -68,7 +68,7 @@ import sympy as sp from pystencils import fields, kernel from pystencilssfg import SourceFileGenerator -from pystencilssfg.lang.cpp import mdspan_ref +from pystencilssfg.lang.cpp import std with SourceFileGenerator() as sfg: u_src, u_dst, f = fields("u_src, u_dst, f(1) : double[2D]", layout="fzyx") @@ -81,9 +81,9 @@ with SourceFileGenerator() as sfg: poisson_kernel = sfg.kernels.create(poisson_jacobi) sfg.function("jacobi_smooth")( - sfg.map_field(u_src, mdspan_ref(u_src)), - sfg.map_field(u_dst, mdspan_ref(u_dst)), - sfg.map_field(f, mdspan_ref(f)), + sfg.map_field(u_src, std.mdspan.from_field(u_src)), + sfg.map_field(u_dst, std.mdspan.from_field(u_dst)), + sfg.map_field(f, std.mdspan.from_field(f)), sfg.call(poisson_kernel) ) ``` @@ -102,11 +102,11 @@ python poisson_smoother.py ``` During execution, *pystencils-sfg* assembles the above constructs into an internal representation of the C++ files. -It then takes the name of your Python script, replaces `.py` with `.cpp` and `.h`, +It then takes the name of your Python script, replaces `.py` with `.cpp` and `.hpp`, and exports the constructed code to the files -`poisson_smoother.cpp` and `poisson_smoother.h` into the current directory, ready to be `#include`d. +`poisson_smoother.cpp` and `poisson_smoother.hpp` into the current directory, ready to be `#include`d. -````{dropdown} poisson_smoother.h +````{dropdown} poisson_smoother.hpp ```C++ #pragma once @@ -129,7 +129,7 @@ void jacobi_smooth( ````{dropdown} poisson_smoother.cpp ```C++ -#include "poisson_smoother.h" +#include "poisson_smoother.hpp" #include <math.h> diff --git a/docs/source/usage/examples/guide_generator_scripts/05/kernels.py b/docs/source/usage/examples/guide_generator_scripts/05/kernels.py index 431c4cf365a52ca4f9504a6c43aa3c7ebce3d535..27cebb8489f10ed15899bbb5020382abd05c9461 100644 --- a/docs/source/usage/examples/guide_generator_scripts/05/kernels.py +++ b/docs/source/usage/examples/guide_generator_scripts/05/kernels.py @@ -21,8 +21,8 @@ with SourceFileGenerator() as sfg: sfg.include("<span>") sfg.function("scale_kernel")( - sfg.map_field(src, std.vector(src)), - sfg.map_field(dst, std.span(dst)), + sfg.map_field(src, std.vector.from_field(src)), + sfg.map_field(dst, std.span.from_field(dst)), sfg.call(scale_kernel) ) # end diff --git a/pyproject.toml b/pyproject.toml index 0a3cde6b11c7e282bb05bff349cb75c21f7bec80..f942a18536ef30209cf48ecc320b4e625fd30a6c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,10 +23,13 @@ requires = [ build-backend = "setuptools.build_meta" [project.optional-dependencies] -testing = [ +tests = [ "flake8>=6.1.0", "mypy>=1.7.0", - "black" + "black", + "pyyaml", + "requests", + "fasteners", ] docs = [ "sphinx", @@ -54,3 +57,10 @@ omit = [ "src/pystencilssfg/_version.py", "integration/*" ] + +[tool.coverage.report] +exclude_also = [ + "\\.\\.\\.", + "if TYPE_CHECKING:", + "@(abc\\.)?abstractmethod", +] diff --git a/pytest.ini b/pytest.ini index 7dc0d3812dee41d0511ea766ec4e8b032760bf60..91afe80606639eb5ad33c77d899d7eb57b91d107 100644 --- a/pytest.ini +++ b/pytest.ini @@ -5,8 +5,9 @@ python_files = "test_*.py" # during test collection addopts = --doctest-modules - --ignore=tests/generator_scripts/scripts - --ignore=tests/generator_scripts/config + --ignore=tests/generator_scripts/source + --ignore=tests/generator_scripts/deps + --ignore=tests/generator_scripts/expected --ignore=tests/data doctest_optionflags = NORMALIZE_WHITESPACE IGNORE_EXCEPTION_DETAIL diff --git a/src/pystencilssfg/composer/basic_composer.py b/src/pystencilssfg/composer/basic_composer.py index d54659626d6c23f36d24b62ea59bdb5e04c7470b..c48410c0619482dcbe44de21742727e1b27ade8e 100644 --- a/src/pystencilssfg/composer/basic_composer.py +++ b/src/pystencilssfg/composer/basic_composer.py @@ -30,7 +30,6 @@ from ..ir import ( SfgSwitch, ) from ..ir.postprocessing import ( - SfgDeferredParamMapping, SfgDeferredParamSetter, SfgDeferredFieldMapping, SfgDeferredVectorMapping, @@ -52,11 +51,14 @@ from ..lang import ( _ExprLike, asvar, depends, + HeaderFile, + includes, SfgVar, AugExpr, SrcField, IFieldExtraction, SrcVector, + void, ) from ..exceptions import SfgException @@ -217,7 +219,7 @@ class SfgBasicComposer(SfgIComposer): #include <vector> #include "custom.h" """ - self._ctx.add_include(SfgHeaderInclude.parse(header_file, private)) + self._ctx.add_include(SfgHeaderInclude(HeaderFile.parse(header_file), private)) def numpy_struct( self, name: str, dtype: np.dtype, add_constructor: bool = True @@ -256,7 +258,7 @@ class SfgBasicComposer(SfgIComposer): func = SfgFunction(name, tree) self._ctx.add_function(func) - def function(self, name: str): + def function(self, name: str, return_type: UserTypeSpec = void): """Add a function. The syntax of this function adder uses a chain of two calls to mimic C++ syntax: @@ -274,7 +276,7 @@ class SfgBasicComposer(SfgIComposer): def sequencer(*args: SequencerArg): tree = make_sequence(*args) - func = SfgFunction(name, tree) + func = SfgFunction(name, tree, return_type=create_type(return_type)) self._ctx.add_function(func) return sequencer @@ -318,11 +320,9 @@ class SfgBasicComposer(SfgIComposer): """Use inside a function body to add parameters to the function.""" return SfgFunctionParams([x.as_variable() for x in args]) - def require(self, *includes: str | SfgHeaderInclude) -> SfgRequireIncludes: + def require(self, *incls: str | HeaderFile) -> SfgRequireIncludes: """Use inside a function body to require the inclusion of headers.""" - return SfgRequireIncludes( - list(SfgHeaderInclude.parse(incl) for incl in includes) - ) + return SfgRequireIncludes((HeaderFile.parse(incl) for incl in incls)) def cpptype( self, @@ -385,10 +385,12 @@ class SfgBasicComposer(SfgIComposer): def parse_args(*args: ExprLike): args_str = ", ".join(str(arg) for arg in args) deps: set[SfgVar] = reduce(set.union, (depends(arg) for arg in args), set()) + incls: set[HeaderFile] = reduce(set.union, (includes(arg) for arg in args)) return SfgStatements( f"{lhs_var.dtype.c_string()} {lhs_var.name} {{ {args_str} }};", (lhs_var,), deps, + incls, ) return parse_args @@ -443,9 +445,14 @@ class SfgBasicComposer(SfgIComposer): """ return SfgBranchBuilder() - def switch(self, switch_arg: ExprLike) -> SfgSwitchBuilder: - """Use inside a function to construct a switch-case statement.""" - return SfgSwitchBuilder(switch_arg) + def switch(self, switch_arg: ExprLike, autobreak: bool = True) -> SfgSwitchBuilder: + """Use inside a function to construct a switch-case statement. + + Args: + switch_arg: Argument to the `switch()` statement + autobreak: Whether to automatically print a `break;` at the end of each case block + """ + return SfgSwitchBuilder(switch_arg, autobreak=autobreak) def map_field( self, @@ -466,30 +473,14 @@ class SfgBasicComposer(SfgIComposer): ) def set_param(self, param: VarLike | sp.Symbol, expr: ExprLike): - deps = depends(expr) - var: SfgVar | sp.Symbol = asvar(param) if isinstance(param, _VarLike) else param - return SfgDeferredParamSetter(var, deps, str(expr)) - - def map_param( - self, - param: VarLike | sp.Symbol, - depends: VarLike | Sequence[VarLike], - mapping: str, - ): - from warnings import warn - - warn( - "The `map_param` method of `SfgBasicComposer` is deprecated and will be removed " - "in a future version. Use `sfg.set_param` instead.", - FutureWarning, - ) + """Set a kernel parameter to an expression. - if isinstance(depends, _VarLike): - depends = [depends] - lhs_var: SfgVar | sp.Symbol = ( - asvar(param) if isinstance(param, _VarLike) else param - ) - return SfgDeferredParamMapping(lhs_var, set(asvar(v) for v in depends), mapping) + Code setting the parameter will only be generated if the parameter + is actually alive (i.e. required by some kernel, and not yet set) at + the point this method is called. + """ + var: SfgVar | sp.Symbol = asvar(param) if isinstance(param, _VarLike) else param + return SfgDeferredParamSetter(var, expr) def map_vector(self, lhs_components: Sequence[VarLike | sp.Symbol], rhs: SrcVector): """Extracts scalar numerical values from a vector data type. @@ -505,7 +496,7 @@ class SfgBasicComposer(SfgIComposer): def make_statements(arg: ExprLike) -> SfgStatements: - return SfgStatements(str(arg), (), depends(arg)) + return SfgStatements(str(arg), (), depends(arg), includes(arg)) def make_sequence(*args: SequencerArg) -> SfgSequence: @@ -613,16 +604,19 @@ class SfgBranchBuilder(SfgNodeBuilder): class SfgSwitchBuilder(SfgNodeBuilder): """Builder for C++ switches.""" - def __init__(self, switch_arg: ExprLike): + def __init__(self, switch_arg: ExprLike, autobreak: bool = True): self._switch_arg = switch_arg self._cases: dict[str, SfgSequence] = dict() self._default: SfgSequence | None = None + self._autobreak = autobreak def case(self, label: str): if label in self._cases: raise SfgException(f"Duplicate case: {label}") def sequencer(*args: SequencerArg): + if self._autobreak: + args += ("break;",) tree = make_sequence(*args) self._cases[label] = tree return self diff --git a/src/pystencilssfg/emission/header_impl_pair.py b/src/pystencilssfg/emission/header_impl_pair.py index d70cfd255e5df6d01169eea50fe4ac87bba37bdf..87ff5f55c1484ffd8e5afd1eb53c0349c7c961e8 100644 --- a/src/pystencilssfg/emission/header_impl_pair.py +++ b/src/pystencilssfg/emission/header_impl_pair.py @@ -2,7 +2,6 @@ from typing import Sequence from os import path, makedirs from ..context import SfgContext -from .prepare import prepare_context from .printers import SfgHeaderPrinter, SfgImplPrinter from .clang_format import invoke_clang_format from ..config import ClangFormatOptions @@ -40,8 +39,6 @@ class HeaderImplPairEmitter(AbstractEmitter): def write_files(self, ctx: SfgContext): """Write the code represented by the given [SfgContext][pystencilssfg.SfgContext] to the files specified by the output specification.""" - ctx = prepare_context(ctx) - header_printer = SfgHeaderPrinter(ctx, self._ospec, self._inline_impl) impl_printer = SfgImplPrinter(ctx, self._ospec, self._inline_impl) diff --git a/src/pystencilssfg/emission/header_only.py b/src/pystencilssfg/emission/header_only.py index ce6ce90f609f110153c5d5ae753d0d511540ab18..7d026da7aea8b32495bba6c2298adfb35ff4fb00 100644 --- a/src/pystencilssfg/emission/header_only.py +++ b/src/pystencilssfg/emission/header_only.py @@ -2,7 +2,6 @@ from typing import Sequence from os import path, makedirs from ..context import SfgContext -from .prepare import prepare_context from .printers import SfgHeaderPrinter from ..config import ClangFormatOptions from .clang_format import invoke_clang_format @@ -28,8 +27,6 @@ class HeaderOnlyEmitter(AbstractEmitter): return (path.join(self._output_directory, self._header_filename),) def write_files(self, ctx: SfgContext): - ctx = prepare_context(ctx) - header_printer = SfgHeaderPrinter(ctx, self._ospec) header = header_printer.get_code() if self._clang_format is not None: diff --git a/src/pystencilssfg/emission/prepare.py b/src/pystencilssfg/emission/prepare.py deleted file mode 100644 index 55e7fe035d0561f2579f7badc6f7588ac243ab4e..0000000000000000000000000000000000000000 --- a/src/pystencilssfg/emission/prepare.py +++ /dev/null @@ -1,88 +0,0 @@ -from __future__ import annotations - -from typing import TYPE_CHECKING - -from functools import reduce - -from ..exceptions import SfgException -from ..ir import SfgCallTreeNode -from ..ir.source_components import ( - SfgFunction, - SfgClass, - SfgConstructor, - SfgMemberVariable, - SfgInClassDefinition, -) -from ..context import SfgContext - -if TYPE_CHECKING: - from ..ir.source_components import SfgHeaderInclude - - -class CollectIncludes: - def __call__(self, obj: object) -> set[SfgHeaderInclude]: - return self.visit(obj) - - def visit(self, obj: object) -> set[SfgHeaderInclude]: - match obj: - case SfgContext(): - includes = set() - for func in obj.functions(): - includes |= self.visit(func) - - for cls in obj.classes(): - includes |= self.visit(cls) - - return includes - - case SfgCallTreeNode(): - return reduce( - lambda accu, child: accu | self.visit(child), - obj.children, - obj.required_includes, - ) - - case SfgFunction(_, tree, _): - return self.visit(tree) - - case SfgClass(): - return reduce( - lambda accu, member: accu | (self.visit(member)), - obj.members(), - set(), - ) - - case SfgConstructor(): - return reduce( - lambda accu, obj: accu | obj.required_includes, - obj.parameters, - set(), - ) - - case SfgMemberVariable(): - return obj.required_includes - - case SfgInClassDefinition(): - return set() - - case _: - raise SfgException( - f"Can't collect includes from object of type {type(obj)}" - ) - - -def prepare_context(ctx: SfgContext): - """Prepares a populated context for printing. Make sure to run this function on the - [SfgContext][pystencilssfg.SfgContext] before passing it to a printer. - - Steps: - - Collection of includes: All defined functions and classes are traversed to collect all required - header includes - """ - - # Collect all includes - required_includes = CollectIncludes().visit(ctx) - for incl in required_includes: - ctx.add_include(incl) - - return ctx diff --git a/src/pystencilssfg/emission/printers.py b/src/pystencilssfg/emission/printers.py index 6daccfa0c5edab18fa4c509ad8eb379a5f163204..eb05ff6efa8eb8166c6d5f81e8e4596c6c797704 100644 --- a/src/pystencilssfg/emission/printers.py +++ b/src/pystencilssfg/emission/printers.py @@ -115,7 +115,7 @@ class SfgHeaderPrinter(SfgGeneralPrinter): def function(self, func: SfgFunction): params = sorted(list(func.parameters), key=lambda p: p.name) param_list = ", ".join(f"{param.dtype.c_string()} {param.name}" for param in params) - return f"{func.return_type} {func.name} ( {param_list} );" + return f"{func.return_type.c_string()} {func.name} ( {param_list} );" @visit.case(SfgClass) def sfg_class(self, cls: SfgClass): @@ -241,7 +241,7 @@ class SfgImplPrinter(SfgGeneralPrinter): def function(self, func: SfgFunction) -> str: inline_prefix = "inline " if self._inline_impl else "" code = ( - f"{inline_prefix} {func.return_type} {func.name} ({self.param_list(func)})" + f"{inline_prefix} {func.return_type.c_string()} {func.name} ({self.param_list(func)})" ) code += ( "{\n" + self._ctx.codestyle.indent(func.tree.get_code(self._ctx)) + "}\n" diff --git a/src/pystencilssfg/extensions/sycl.py b/src/pystencilssfg/extensions/sycl.py index 2f3591cf700adc20dbe810a0ec3ffe07a89b4a29..349e030c6c9057472b9f513258c8a979bba16b8a 100644 --- a/src/pystencilssfg/extensions/sycl.py +++ b/src/pystencilssfg/extensions/sycl.py @@ -3,8 +3,8 @@ from typing import Sequence from enum import Enum import re -from pystencils.types import PsType, PsCustomType -from pystencils.enums import Target +from pystencils.types import UserTypeSpec, PsType, PsCustomType, create_type +from pystencils import Target from pystencilssfg.composer.basic_composer import SequencerArg @@ -17,14 +17,18 @@ from ..composer import ( SfgComposerMixIn, make_sequence, ) -from ..ir.source_components import SfgKernelHandle, SfgHeaderInclude +from ..ir.source_components import SfgKernelHandle from ..ir import ( SfgCallTreeNode, SfgCallTreeLeaf, SfgKernelCallNode, ) -from ..lang import SfgVar, AugExpr +from ..lang import SfgVar, AugExpr, cpptype, Ref, VarLike, _VarLike, asvar +from ..lang.cpp.sycl_accessor import SyclAccessor + + +accessor = SyclAccessor class SyclComposerMixIn(SfgComposerMixIn): @@ -38,9 +42,8 @@ class SyclComposerMixIn(SfgComposerMixIn): """Obtain a `SyclHandler`, which represents a ``sycl::handler`` object.""" return SyclGroup(dims, self._ctx).var(name) - def sycl_range(self, dims: int, name: str, ref: bool = False) -> SfgVar: - ref_str = " &" if ref else "" - return SfgVar(name, PsCustomType(f"sycl::range< {dims} >{ref_str}")) + def sycl_range(self, dims: int, name: str, ref: bool = False) -> SyclRange: + return SyclRange(dims, ref=ref).var(name) class SyclComposer(SfgBasicComposer, SfgClassComposer, SyclComposerMixIn): @@ -50,18 +53,30 @@ class SyclComposer(SfgBasicComposer, SfgClassComposer, SyclComposerMixIn): super().__init__(sfg) +class SyclRange(AugExpr): + _template = cpptype("sycl::range< {dims} >", "<sycl/sycl.hpp>") + + def __init__(self, dims: int, const: bool = False, ref: bool = False): + dtype = self._template(dims=dims, const=const) + if ref: + dtype = Ref(dtype) + super().__init__(dtype) + + class SyclHandler(AugExpr): """Represents a SYCL command group handler (``sycl::handler``).""" + _type = cpptype("sycl::handler", "<sycl/sycl.hpp>") + def __init__(self, ctx: SfgContext): - dtype = PsCustomType("sycl::handler &") + dtype = Ref(self._type()) super().__init__(dtype) self._ctx = ctx def parallel_for( self, - range: SfgVar | Sequence[int], + range: VarLike | Sequence[int], ): """Generate a ``parallel_for`` kernel invocation using this command group handler. The syntax of this uses a chain of two calls to mimic C++ syntax: @@ -77,7 +92,8 @@ class SyclHandler(AugExpr): Args: range: Object, or tuple of integers, indicating the kernel's iteration range """ - self._ctx.add_include(SfgHeaderInclude("sycl/sycl.hpp", system_header=True)) + if isinstance(range, _VarLike): + range = asvar(range) def check_kernel(kernel: SfgKernelHandle): kfunc = kernel.get_kernel_function() @@ -99,7 +115,9 @@ class SyclHandler(AugExpr): for arg in args: if isinstance(arg, SfgKernelCallNode): check_kernel(arg._kernel_handle) - id_param.append(list(filter(filter_id, arg._kernel_handle.scalar_parameters))[0]) + id_param.append( + list(filter(filter_id, arg._kernel_handle.scalar_parameters))[0] + ) if not all(item == id_param[0] for item in id_param): raise ValueError( @@ -118,15 +136,17 @@ class SyclHandler(AugExpr): class SyclGroup(AugExpr): """Represents a SYCL group (``sycl::group``).""" + _template = cpptype("sycl::group< {dims} >", "<sycl/sycl.hpp>") + def __init__(self, dimensions: int, ctx: SfgContext): - dtype = PsCustomType(f"sycl::group< {dimensions} > &") + dtype = Ref(self._template(dims=dimensions)) super().__init__(dtype) self._dimensions = dimensions self._ctx = ctx def parallel_for_work_item( - self, range: SfgVar | Sequence[int], kernel: SfgKernelHandle + self, range: VarLike | Sequence[int], kernel: SfgKernelHandle ): """Generate a ``parallel_for_work_item` kernel invocation on this group.` @@ -134,8 +154,8 @@ class SyclGroup(AugExpr): range: Object, or tuple of integers, indicating the kernel's iteration range kernel: Handle to the pystencils-kernel to be executed """ - - self._ctx.add_include(SfgHeaderInclude("sycl/sycl.hpp", system_header=True)) + if isinstance(range, _VarLike): + range = asvar(range) kfunc = kernel.get_kernel_function() if kfunc.target != Target.SYCL: @@ -156,18 +176,15 @@ class SyclGroup(AugExpr): comp = SfgComposer(self._ctx) tree = comp.seq( - comp.map_param( - id_param, - h_item, - f"{id_param.dtype.c_string()} {id_param.name} = {h_item}.get_local_id();", - ), + comp.set_param(id_param, AugExpr.format("{}.get_local_id()", h_item)), SfgKernelCallNode(kernel), ) kernel_lambda = SfgLambda(("=",), (h_item,), tree, None) - return SyclKernelInvoke( + invoke = SyclKernelInvoke( self, SyclInvokeType.ParallelForWorkItem, range, kernel_lambda ) + return invoke class SfgLambda: @@ -178,12 +195,14 @@ class SfgLambda: captures: Sequence[str], params: Sequence[SfgVar], tree: SfgCallTreeNode, - return_type: PsType | None = None, + return_type: UserTypeSpec | None = None, ) -> None: self._captures = tuple(captures) self._params = tuple(params) self._tree = tree - self._return_type = return_type + self._return_type: PsType | None = ( + create_type(return_type) if return_type is not None else None + ) from ..ir.postprocessing import CallTreePostProcessing @@ -262,7 +281,7 @@ class SyclKernelInvoke(SfgCallTreeLeaf): ) self._lambda = lamb - self._required_params = invoker.depends | lamb.required_parameters + self._required_params = set(invoker.depends | lamb.required_parameters) if isinstance(range, SfgVar): self._required_params.add(range) diff --git a/src/pystencilssfg/generator.py b/src/pystencilssfg/generator.py index cc9cd6252604cd9bedb42a995c7c242a61e117d4..eed06b0d684850e462b86aa11b53bc4ca1586185 100644 --- a/src/pystencilssfg/generator.py +++ b/src/pystencilssfg/generator.py @@ -74,9 +74,10 @@ class SourceFileGenerator: project_info=cli_params.get_project_info(), ) - from pystencilssfg.ir import SfgHeaderInclude + from .lang import HeaderFile + from .ir import SfgHeaderInclude - self._context.add_include(SfgHeaderInclude("cstdint", system_header=True)) + self._context.add_include(SfgHeaderInclude(HeaderFile("cstdint", system_header=True))) self._context.add_definition("#define RESTRICT __restrict__") output_mode = config.get_option("output_mode") @@ -114,4 +115,9 @@ class SourceFileGenerator: def __exit__(self, exc_type, exc_value, traceback): if exc_type is None: + # Collect header files for inclusion + from .ir import SfgHeaderInclude, collect_includes + for header in collect_includes(self._context): + self._context.add_include(SfgHeaderInclude(header)) + self._emitter.write_files(self._context) diff --git a/src/pystencilssfg/ir/__init__.py b/src/pystencilssfg/ir/__init__.py index 9ab366cbd65373639e2123b9d896ab2839225166..8eee39cfc2e5fa6e37f677dd780aa35bb9a796b6 100644 --- a/src/pystencilssfg/ir/__init__.py +++ b/src/pystencilssfg/ir/__init__.py @@ -31,6 +31,7 @@ from .source_components import ( SfgConstructor, SfgClass, ) +from .analysis import collect_includes __all__ = [ "SfgCallTreeNode", @@ -61,4 +62,5 @@ __all__ = [ "SfgMethod", "SfgConstructor", "SfgClass", + "collect_includes" ] diff --git a/src/pystencilssfg/ir/analysis.py b/src/pystencilssfg/ir/analysis.py new file mode 100644 index 0000000000000000000000000000000000000000..0b42594033da16efbde3ab8da3433dfcad03a097 --- /dev/null +++ b/src/pystencilssfg/ir/analysis.py @@ -0,0 +1,67 @@ +from __future__ import annotations +from typing import Any + +from functools import reduce + +from ..exceptions import SfgException +from ..lang import HeaderFile, includes + + +def collect_includes(obj: Any) -> set[HeaderFile]: + from ..context import SfgContext + from .call_tree import SfgCallTreeNode + from .source_components import ( + SfgFunction, + SfgClass, + SfgConstructor, + SfgMemberVariable, + SfgInClassDefinition, + ) + + match obj: + case SfgContext(): + headers = set() + for func in obj.functions(): + headers |= collect_includes(func) + + for cls in obj.classes(): + headers |= collect_includes(cls) + + return headers + + case SfgCallTreeNode(): + return reduce( + lambda accu, child: accu | collect_includes(child), + obj.children, + obj.required_includes, + ) + + case SfgFunction(_, tree, parameters): + param_headers: set[HeaderFile] = reduce( + set.union, (includes(p) for p in parameters), set() + ) + return param_headers | collect_includes(tree) + + case SfgClass(): + return reduce( + lambda accu, member: accu | (collect_includes(member)), + obj.members(), + set(), + ) + + case SfgConstructor(parameters): + param_headers = reduce( + set.union, (includes(p) for p in parameters), set() + ) + return param_headers + + case SfgMemberVariable(): + return includes(obj) + + case SfgInClassDefinition(): + return set() + + case _: + raise SfgException( + f"Can't collect includes from object of type {type(obj)}" + ) diff --git a/src/pystencilssfg/ir/call_tree.py b/src/pystencilssfg/ir/call_tree.py index 4a084649b068487a5e712fb1d7f49f87153bc5ee..c6f4951db4397d356c80340ae99f4bf2b8ef1b8e 100644 --- a/src/pystencilssfg/ir/call_tree.py +++ b/src/pystencilssfg/ir/call_tree.py @@ -2,10 +2,9 @@ from __future__ import annotations from typing import TYPE_CHECKING, Sequence, Iterable, NewType from abc import ABC, abstractmethod -from itertools import chain -from .source_components import SfgHeaderInclude, SfgKernelHandle -from ..lang import SfgVar +from .source_components import SfgKernelHandle +from ..lang import SfgVar, HeaderFile if TYPE_CHECKING: from ..context import SfgContext @@ -27,6 +26,8 @@ class SfgCallTreeNode(ABC): the branching structure through the `children` property and the `child` and `set_child` methods is possible, if necessary by overriding the property and methods. """ + def __init__(self) -> None: + self._includes: set[HeaderFile] = set() @property @abstractmethod @@ -41,9 +42,9 @@ class SfgCallTreeNode(ABC): """ @property - def required_includes(self) -> set[SfgHeaderInclude]: + def required_includes(self) -> set[HeaderFile]: """Return a set of header includes required by this node""" - return set() + return self._includes class SfgCallTreeLeaf(SfgCallTreeNode, ABC): @@ -99,6 +100,7 @@ class SfgStatements(SfgCallTreeLeaf): code_string: str, defines: Iterable[SfgVar], depends: Iterable[SfgVar], + includes: Iterable[HeaderFile] = (), ): super().__init__() @@ -106,11 +108,7 @@ class SfgStatements(SfgCallTreeLeaf): self._defines = set(defines) self._depends = set(depends) - - self._required_includes = set() - for obj in chain(depends, defines): - if isinstance(obj, SfgVar): - self._required_includes |= obj.required_includes + self._includes = set(includes) @property def depends(self) -> set[SfgVar]: @@ -120,10 +118,6 @@ class SfgStatements(SfgCallTreeLeaf): def defines(self) -> set[SfgVar]: return self._defines - @property - def required_includes(self) -> set[SfgHeaderInclude]: - return self._required_includes - @property def code_string(self) -> str: return self._code_string @@ -137,38 +131,26 @@ class SfgFunctionParams(SfgEmptyNode): super().__init__() self._params = set(parameters) - self._required_includes = set() - for obj in parameters: - if isinstance(obj, SfgVar): - self._required_includes |= obj.required_includes - @property def depends(self) -> set[SfgVar]: return self._params - @property - def required_includes(self) -> set[SfgHeaderInclude]: - return self._required_includes - class SfgRequireIncludes(SfgEmptyNode): - def __init__(self, includes: Sequence[SfgHeaderInclude]): + def __init__(self, includes: Iterable[HeaderFile]): super().__init__() - self._required_includes = set(includes) + self._includes = set(includes) @property def depends(self) -> set[SfgVar]: return set() - @property - def required_includes(self) -> set[SfgHeaderInclude]: - return self._required_includes - class SfgSequence(SfgCallTreeNode): __match_args__ = ("children",) def __init__(self, children: Sequence[SfgCallTreeNode]): + super().__init__() self._children = list(children) @property @@ -191,6 +173,7 @@ class SfgSequence(SfgCallTreeNode): class SfgBlock(SfgCallTreeNode): def __init__(self, seq: SfgSequence): + super().__init__() self._seq = seq @property @@ -282,6 +265,7 @@ class SfgBranch(SfgCallTreeNode): branch_true: SfgSequence, branch_false: SfgSequence | None = None, ): + super().__init__() self._cond = cond self._branch_true = branch_true self._branch_false = branch_false @@ -323,6 +307,7 @@ class SfgSwitchCase(SfgCallTreeNode): Default = DefaultCaseType(object()) def __init__(self, label: str | SfgSwitchCase.DefaultCaseType, body: SfgSequence): + super().__init__() self._label = label self._body = body @@ -349,7 +334,7 @@ class SfgSwitchCase(SfgCallTreeNode): else: code += f"case {self._label}: {{\n" code += ctx.codestyle.indent(self.body.get_code(ctx)) - code += "\nbreak;\n}" + code += "\n}" return code @@ -360,6 +345,7 @@ class SfgSwitch(SfgCallTreeNode): cases_dict: dict[str, SfgSequence], default: SfgSequence | None = None, ): + super().__init__() self._cases = [SfgSwitchCase(label, body) for label, body in cases_dict.items()] if default is not None: # invariant: the default case is always the last child @@ -419,6 +405,6 @@ class SfgSwitch(SfgCallTreeNode): def get_code(self, ctx: SfgContext) -> str: code = f"switch({self._switch_arg.get_code(ctx)}) {{\n" - code += "\n".join(c.get_code(ctx) for c in self.children) + code += "\n".join(c.get_code(ctx) for c in self._cases) code += "}" return code diff --git a/src/pystencilssfg/ir/postprocessing.py b/src/pystencilssfg/ir/postprocessing.py index 638a55f30f41f26f531a69a346b083dddd901797..d9d59911464e885e528cba6fa1b0e9ad9f8511b8 100644 --- a/src/pystencilssfg/ir/postprocessing.py +++ b/src/pystencilssfg/ir/postprocessing.py @@ -16,7 +16,16 @@ from ..exceptions import SfgException from .call_tree import SfgCallTreeNode, SfgCallTreeLeaf, SfgSequence, SfgStatements from ..ir.source_components import SfgKernelParamVar -from ..lang import SfgVar, IFieldExtraction, SrcField, SrcVector, AugExpr +from ..lang import ( + SfgVar, + IFieldExtraction, + SrcField, + SrcVector, + ExprLike, + AugExpr, + depends, + includes, +) if TYPE_CHECKING: from ..context import SfgContext @@ -210,31 +219,16 @@ class SfgDeferredNode(SfgCallTreeNode, ABC): ) -class SfgDeferredParamMapping(SfgDeferredNode): - def __init__(self, lhs: SfgVar | sp.Symbol, depends: set[SfgVar], mapping: str): - self._lhs = lhs - self._depends = depends - self._mapping = mapping - - def expand(self, ppc: PostProcessingContext) -> SfgCallTreeNode: - live_var = ppc.get_live_variable(self._lhs.name) - if live_var is not None: - return SfgStatements(self._mapping, (live_var,), tuple(self._depends)) - else: - return SfgSequence([]) - - class SfgDeferredParamSetter(SfgDeferredNode): - def __init__(self, param: SfgVar | sp.Symbol, depends: set[SfgVar], rhs_expr: str): + def __init__(self, param: SfgVar | sp.Symbol, rhs: ExprLike): self._lhs = param - self._depends = depends - self._rhs_expr = rhs_expr + self._rhs = rhs def expand(self, ppc: PostProcessingContext) -> SfgCallTreeNode: live_var = ppc.get_live_variable(self._lhs.name) if live_var is not None: - code = f"{live_var.dtype.c_string()} {live_var.name} = {self._rhs_expr};" - return SfgStatements(code, (live_var,), tuple(self._depends)) + code = f"{live_var.dtype.c_string()} {live_var.name} = {self._rhs};" + return SfgStatements(code, (live_var,), depends(self._rhs), includes(self._rhs)) else: return SfgSequence([]) @@ -291,13 +285,18 @@ class SfgDeferredFieldMapping(SfgDeferredNode): expr = self._extraction.ptr() nodes.append( SfgStatements( - f"{ptr.dtype.c_string()} {ptr.name} {{ {expr} }};", (ptr,), expr.depends + f"{ptr.dtype.c_string()} {ptr.name} {{ {expr} }};", + (ptr,), + depends(expr), + includes(expr), ) ) def maybe_cast(expr: AugExpr, target_type: PsType) -> AugExpr: if self._cast_indexing_symbols: - return AugExpr(target_type).bind("{}( {} )", deconstify(target_type).c_string(), expr) + return AugExpr(target_type).bind( + "{}( {} )", deconstify(target_type).c_string(), expr + ) else: return expr @@ -313,7 +312,10 @@ class SfgDeferredFieldMapping(SfgDeferredNode): done.add(symb) expr = maybe_cast(expr, symb.dtype) return SfgStatements( - f"{symb.dtype.c_string()} {symb.name} {{ {expr} }};", (symb,), expr.depends + f"{symb.dtype.c_string()} {symb.name} {{ {expr} }};", + (symb,), + depends(expr), + includes(expr), ) else: return SfgStatements(f"/* {expr} == {symb} */", (), ()) @@ -330,7 +332,10 @@ class SfgDeferredFieldMapping(SfgDeferredNode): done.add(symb) expr = maybe_cast(expr, symb.dtype) return SfgStatements( - f"{symb.dtype.c_string()} {symb.name} {{ {expr} }};", (symb,), expr.depends + f"{symb.dtype.c_string()} {symb.name} {{ {expr} }};", + (symb,), + depends(expr), + includes(expr), ) else: return SfgStatements(f"/* {expr} == {symb} */", (), ()) @@ -357,7 +362,8 @@ class SfgDeferredVectorMapping(SfgDeferredNode): SfgStatements( f"{param.dtype.c_string()} {param.name} {{ {expr} }};", (param,), - expr.depends, + depends(expr), + includes(expr), ) ) diff --git a/src/pystencilssfg/ir/source_components.py b/src/pystencilssfg/ir/source_components.py index cf4d103a2a93e363e73282a31eb0b6523f510c6e..13c4b5092e2d5926ecdd549eab45737bf05fc625 100644 --- a/src/pystencilssfg/ir/source_components.py +++ b/src/pystencilssfg/ir/source_components.py @@ -13,7 +13,7 @@ from pystencils.backend.kernelfunction import ( ) from pystencils.types import PsType, PsCustomType -from ..lang import SfgVar +from ..lang import SfgVar, HeaderFile, void from ..exceptions import SfgException if TYPE_CHECKING: @@ -33,45 +33,31 @@ class SfgEmptyLines: class SfgHeaderInclude: """Represent ``#include``-directives.""" - @staticmethod - def parse(incl: str | SfgHeaderInclude, private: bool = False): - if isinstance(incl, SfgHeaderInclude): - return incl - - system_header = False - if incl.startswith("<") and incl.endswith(">"): - incl = incl[1:-1] - system_header = True - - return SfgHeaderInclude(incl, system_header=system_header, private=private) - def __init__( - self, header_file: str, system_header: bool = False, private: bool = False + self, header_file: HeaderFile, private: bool = False ): self._header_file = header_file - self._system_header = system_header self._private = private @property def file(self) -> str: - return self._header_file + return self._header_file.filepath @property def system_header(self): - return self._system_header + return self._header_file.system_header @property def private(self): return self._private def __hash__(self) -> int: - return hash((self._header_file, self._system_header, self._private)) + return hash((self._header_file, self._private)) def __eq__(self, other: object) -> bool: return ( isinstance(other, SfgHeaderInclude) and self._header_file == other._header_file - and self._system_header == other._system_header and self._private == other._private ) @@ -119,7 +105,7 @@ class SfgKernelNamespace: self._kernel_functions[astname] = kernel for header in kernel.required_headers: - self._ctx.add_include(SfgHeaderInclude.parse(header, private=True)) + self._ctx.add_include(SfgHeaderInclude(HeaderFile.parse(header), private=True)) return SfgKernelHandle(self._ctx, astname, self, kernel.parameters) @@ -231,7 +217,7 @@ class SfgFunction: self, name: str, tree: SfgCallTreeNode, - return_type: PsType = PsCustomType("void"), + return_type: PsType = void, _is_method: bool = False, ): self._name = name @@ -409,6 +395,8 @@ class SfgMethod(SfgFunction, SfgClassMember): class SfgConstructor(SfgClassMember): + __match_args__ = ("parameters", "initializers", "body") + def __init__( self, parameters: Sequence[SfgVar] = (), diff --git a/src/pystencilssfg/lang/__init__.py b/src/pystencilssfg/lang/__init__.py index b5532bf77464dbc1e32f8449158ec4ae34418f30..2ad8f9384be3e5f93e78b2504e2e90b730d345da 100644 --- a/src/pystencilssfg/lang/__init__.py +++ b/src/pystencilssfg/lang/__init__.py @@ -1,3 +1,5 @@ +from .headers import HeaderFile + from .expressions import ( SfgVar, AugExpr, @@ -7,14 +9,16 @@ from .expressions import ( _ExprLike, asvar, depends, + includes, IFieldExtraction, SrcField, SrcVector, ) -from .types import Ref, strip_ptr_ref +from .types import cpptype, void, Ref, strip_ptr_ref __all__ = [ + "HeaderFile", "SfgVar", "AugExpr", "VarLike", @@ -23,9 +27,12 @@ __all__ = [ "_ExprLike", "asvar", "depends", + "includes", "IFieldExtraction", "SrcField", "SrcVector", + "cpptype", + "void", "Ref", "strip_ptr_ref" ] diff --git a/src/pystencilssfg/lang/cpp/__init__.py b/src/pystencilssfg/lang/cpp/__init__.py index a00c2c2b3ea1c279f04ef6d460320b97aad60111..faa98956c66dddf69d7e534f2b3d85567d76bbc7 100644 --- a/src/pystencilssfg/lang/cpp/__init__.py +++ b/src/pystencilssfg/lang/cpp/__init__.py @@ -1,6 +1,6 @@ from .std_mdspan import StdMdspan, mdspan_ref from .std_vector import StdVector, std_vector_ref -from .std_tuple import StdTuple, std_tuple_ref +from .std_tuple import StdTuple from .std_span import StdSpan, std_span_ref __all__ = [ @@ -9,7 +9,6 @@ __all__ = [ "StdVector", "std_vector_ref", "StdTuple", - "std_tuple_ref", "StdSpan", "std_span_ref", ] diff --git a/src/pystencilssfg/lang/cpp/std.py b/src/pystencilssfg/lang/cpp/std.py index 48cd249496b182eb911f1264a8e1a5410aa141e3..4a98f19c9625d8b91044f0f29be826eb2189955c 100644 --- a/src/pystencilssfg/lang/cpp/std.py +++ b/src/pystencilssfg/lang/cpp/std.py @@ -1,12 +1,9 @@ -from .std_span import std_span_ref -from .std_mdspan import mdspan_ref -from .std_vector import std_vector_ref +from .std_span import StdSpan +from .std_mdspan import StdMdspan +from .std_vector import StdVector +from .std_tuple import StdTuple -span = std_span_ref -"""Create an ``std::span`` reference for a 1D pystencils field""" - -mdspan = mdspan_ref -"""Create an ``std::mdspan`` reference for a pystencils field""" - -vector = std_vector_ref -"""Create an ``std::vector`` reference for a 1D pystencils field""" +span = StdSpan +mdspan = StdMdspan +vector = StdVector +tuple = StdTuple diff --git a/src/pystencilssfg/lang/cpp/std_mdspan.py b/src/pystencilssfg/lang/cpp/std_mdspan.py index 0b460fd13e7a924f17a3745bf230add517be53c1..2ede10864d6745ea71605af9b1dd6f565f549155 100644 --- a/src/pystencilssfg/lang/cpp/std_mdspan.py +++ b/src/pystencilssfg/lang/cpp/std_mdspan.py @@ -4,45 +4,65 @@ from sympy import Symbol from pystencils import Field from pystencils.types import ( PsType, - PsCustomType, - PsSignedIntegerType, PsUnsignedIntegerType, + UserTypeSpec, + create_type, ) from pystencilssfg.lang.expressions import AugExpr -from ...lang import SrcField, IFieldExtraction -from ...ir.source_components import SfgHeaderInclude +from ...lang import SrcField, IFieldExtraction, cpptype, Ref, HeaderFile class StdMdspan(SrcField): + """Represents an `std::mdspan` instance. + + **On Standard Library Adoption** + + Since `std::mdspan` is not yet widely adopted + (libc++ ships it as of LLVM 18, but GCC libstdc++ does not include it yet), + you might have to manually include an implementation in your project + (you can get a reference implementation [here](https://github.com/kokkos/mdspan)). + However, when working with a non-standard mdspan implementation, + the path to its the header and the namespace it is defined in will likely be different. + + To tell pystencils-sfg which headers to include and which namespace to use for `mdspan`, + use `StdMdspan.configure`. + """ + dynamic_extent = "std::dynamic_extent" + _namespace = "std" + _template = cpptype("std::mdspan< {T}, {extents} >", "<mdspan>") + + @classmethod + def configure(cls, namespace: str = "std", header: str | HeaderFile = "<mdspan>"): + """Configure the namespace and header `mdspan` is defined in.""" + cls._namespace = namespace + cls._template = cpptype(f"{namespace}::mdspan< {{T}}, {{extents}} >", header) + def __init__( self, - T: PsType, + T: UserTypeSpec, extents: tuple[int | str, ...], - extents_type: PsType = PsSignedIntegerType(64), - reference: bool = False, + extents_type: PsType = PsUnsignedIntegerType(64), + ref: bool = False, + const: bool = False, ): - cpp_typestr = T.c_string() + T = create_type(T) + extents_type_str = extents_type.c_string() + extents_str = f"{self._namespace}::extents< {extents_type_str}, {', '.join(str(e) for e in extents)} >" - extents_str = ( - f"std::extents< {extents_type_str}, {', '.join(str(e) for e in extents)} >" - ) - typestring = ( - f"std::mdspan< {cpp_typestr}, {extents_str} > {'&' if reference else ''}" - ) - super().__init__(PsCustomType(typestring)) + dtype = self._template(T=T, extents=extents_str, const=const) + + if ref: + dtype = Ref(dtype) + super().__init__(dtype) self._extents = extents self._dim = len(extents) - @property - def required_includes(self) -> set[SfgHeaderInclude]: - return {SfgHeaderInclude("experimental/mdspan", system_header=True)} - def get_extraction(self) -> IFieldExtraction: mdspan = self @@ -64,29 +84,41 @@ class StdMdspan(SrcField): return Extraction() + @staticmethod + def from_field( + field: Field, + extents_type: PsType = PsUnsignedIntegerType(64), + ref: bool = False, + const: bool = False, + ): + """Creates a `std::mdspan` instance for a given pystencils field.""" + from pystencils.field import layout_string_to_tuple + + if field.layout != layout_string_to_tuple("soa", field.spatial_dimensions): + raise NotImplementedError( + "mdspan mapping is currently only available for structure-of-arrays fields" + ) + + extents: list[str | int] = [] + + for s in field.spatial_shape: + extents.append( + StdMdspan.dynamic_extent if isinstance(s, Symbol) else cast(int, s) + ) + + for s in field.index_shape: + extents.append(StdMdspan.dynamic_extent if isinstance(s, Symbol) else s) + + return StdMdspan( + field.dtype, tuple(extents), extents_type=extents_type, ref=ref, const=const + ).var(field.name) + def mdspan_ref(field: Field, extents_type: PsType = PsUnsignedIntegerType(64)): - """Creates a `std::mdspan &` for a given pystencils field.""" - from pystencils.field import layout_string_to_tuple - - if field.layout != layout_string_to_tuple("soa", field.spatial_dimensions): - raise NotImplementedError( - "mdspan mapping is currently only available for structure-of-arrays fields" - ) - - extents: list[str | int] = [] - - for s in field.spatial_shape: - extents.append( - StdMdspan.dynamic_extent if isinstance(s, Symbol) else cast(int, s) - ) - - for s in field.index_shape: - extents.append(StdMdspan.dynamic_extent if isinstance(s, Symbol) else s) - - return StdMdspan( - field.dtype, - tuple(extents), - extents_type=extents_type, - reference=True, - ).var(field.name) + from warnings import warn + + warn( + "`mdspan_ref` is deprecated and will be removed in version 0.1. Use `std.mdspan.from_field` instead.", + FutureWarning, + ) + return StdMdspan.from_field(field, extents_type, ref=True) diff --git a/src/pystencilssfg/lang/cpp/std_span.py b/src/pystencilssfg/lang/cpp/std_span.py index 37ee04236cdde70a04e7155c2d0f06487b385634..861a4c4bb1ea81b0cbaaef4cb683316274ab2edd 100644 --- a/src/pystencilssfg/lang/cpp/std_span.py +++ b/src/pystencilssfg/lang/cpp/std_span.py @@ -1,24 +1,24 @@ -from typing import Union - from pystencils.field import Field -from pystencils.types import PsType, PsCustomType +from pystencils.types import UserTypeSpec, create_type, PsType -from ...lang import SrcField, IFieldExtraction, AugExpr -from ...ir.source_components import SfgHeaderInclude -from ...exceptions import SfgException +from ...lang import SrcField, IFieldExtraction, AugExpr, cpptype, Ref class StdSpan(SrcField): - def __init__(self, T: Union[PsCustomType, PsType], ref=True, const=False): - src_type = f"{'const ' if const else ''}std::span< {T.c_string()} > {'&' if ref else ''}" + _template = cpptype("std::span< {T} >", "<span>") + + def __init__(self, T: UserTypeSpec, ref=False, const=False): + T = create_type(T) + dtype = self._template(T=T, const=const) + if ref: + dtype = Ref(dtype) + self._element_type = T - super().__init__(PsCustomType(src_type)) + super().__init__(dtype) @property - def required_includes(self) -> set[SfgHeaderInclude]: - return { - SfgHeaderInclude("span", system_header=True), - } + def element_type(self) -> PsType: + return self._element_type def get_extraction(self) -> IFieldExtraction: span = self @@ -41,10 +41,20 @@ class StdSpan(SrcField): return Extraction() + @staticmethod + def from_field(field: Field, ref: bool = False, const: bool = False): + if field.spatial_dimensions > 1 or field.index_shape not in ((), (1,)): + raise ValueError( + "Only one-dimensional fields with trivial index dimensions can be mapped onto `std::span`" + ) + return StdSpan(field.dtype, ref=ref, const=const).var(field.name) + def std_span_ref(field: Field): - if field.spatial_dimensions > 1 or field.index_shape not in ((), (1,)): - raise SfgException( - "Only one-dimensional fields with trivial index dimensions can be mapped onto `std::span`" - ) - return StdSpan(field.dtype, True, False).var(field.name) + from warnings import warn + + warn( + "`std_span_ref` is deprecated and will be removed in version 0.1. Use `std.span.from_field` instead.", + FutureWarning, + ) + return StdSpan.from_field(field, ref=True) diff --git a/src/pystencilssfg/lang/cpp/std_tuple.py b/src/pystencilssfg/lang/cpp/std_tuple.py index 82b2c4d169b23bf38bd08586dec5555aa901c9e9..bbf2ba33b8f1a19081593501885d0dc935fc3055 100644 --- a/src/pystencilssfg/lang/cpp/std_tuple.py +++ b/src/pystencilssfg/lang/cpp/std_tuple.py @@ -1,28 +1,28 @@ from typing import Sequence -from pystencils.types import PsType, PsCustomType -from pystencils.backend.kernelfunction import KernelParameter +from pystencils.types import UserTypeSpec, create_type -from ...lang import SrcVector, AugExpr -from ...ir.source_components import SfgHeaderInclude +from ...lang import SrcVector, AugExpr, cpptype, Ref class StdTuple(SrcVector): + _template = cpptype("std::tuple< {ts} >", "<tuple>") + def __init__( self, - element_types: Sequence[PsType], + element_types: Sequence[UserTypeSpec], const: bool = False, ref: bool = False, ): - self._element_types = element_types + self._element_types = tuple(create_type(t) for t in element_types) self._length = len(element_types) elt_type_strings = tuple(t.c_string() for t in self._element_types) - tuple_type = f"{'const' if const else ''} std::tuple< {', '.join(elt_type_strings)} > {'&' if ref else ''}" - super().__init__(PsCustomType(tuple_type)) - @property - def required_includes(self) -> set[SfgHeaderInclude]: - return {SfgHeaderInclude("tuple", system_header=True)} + dtype = self._template(ts=", ".join(elt_type_strings), const=const) + if ref: + dtype = Ref(dtype) + + super().__init__(dtype) def extract_component(self, coordinate: int) -> AugExpr: if coordinate < 0 or coordinate >= self._length: @@ -31,10 +31,3 @@ class StdTuple(SrcVector): ) return AugExpr.format("std::get< {} >({})", coordinate, self) - - -def std_tuple_ref( - identifier: str, components: Sequence[KernelParameter], const: bool = True -): - elt_types = tuple(c.dtype for c in components) - return StdTuple(elt_types, const=const, ref=True).var(identifier) diff --git a/src/pystencilssfg/lang/cpp/std_vector.py b/src/pystencilssfg/lang/cpp/std_vector.py index a3b4b52f91bcb79b6378051c541719e59048d3cb..5696b32dd55c6092db0ff298fdcbd79fa7df69f5 100644 --- a/src/pystencilssfg/lang/cpp/std_vector.py +++ b/src/pystencilssfg/lang/cpp/std_vector.py @@ -1,28 +1,31 @@ from pystencils.field import Field -from pystencils.types import PsType, PsCustomType +from pystencils.types import UserTypeSpec, create_type, PsType -from ...lang import SrcField, SrcVector, AugExpr, IFieldExtraction -from ...ir.source_components import SfgHeaderInclude +from ...lang import SrcField, SrcVector, AugExpr, IFieldExtraction, cpptype, Ref class StdVector(SrcVector, SrcField): + _template = cpptype("std::vector< {T} >", "<vector>") + def __init__( self, - T: PsType, + T: UserTypeSpec, unsafe: bool = False, - reference: bool = True, + ref: bool = False, + const: bool = False, ): - typestring = f"std::vector< {(T.c_string())} > {'&' if reference else ''}" - super(StdVector, self).__init__(PsCustomType(typestring)) + T = create_type(T) + dtype = self._template(T=T, const=const) + if ref: + dtype = Ref(dtype) + super().__init__(dtype) self._element_type = T self._unsafe = unsafe @property - def required_includes(self) -> set[SfgHeaderInclude]: - return { - SfgHeaderInclude("vector", system_header=True), - } + def element_type(self) -> PsType: + return self._element_type def get_extraction(self) -> IFieldExtraction: vec = self @@ -51,6 +54,21 @@ class StdVector(SrcVector, SrcField): else: return AugExpr.format("{}.at({})", self, coordinate) + @staticmethod + def from_field(field: Field, ref: bool = True, const: bool = False): + if field.spatial_dimensions > 1 or field.index_shape not in ((), (1,)): + raise ValueError( + f"Cannot create std::vector from more-than-one-dimensional field {field}." + ) + + return StdVector(field.dtype, unsafe=False, ref=ref, const=const).var(field.name) + def std_vector_ref(field: Field): - return StdVector(field.dtype, unsafe=False, reference=True).var(field.name) + from warnings import warn + + warn( + "`std_vector_ref` is deprecated and will be removed in version 0.1. Use `std.vector.from_field` instead.", + FutureWarning, + ) + return StdVector.from_field(field, ref=True) diff --git a/src/pystencilssfg/lang/cpp/sycl.py b/src/pystencilssfg/lang/cpp/sycl.py new file mode 100644 index 0000000000000000000000000000000000000000..990acf10167a65a8c02e22bcf1195c7007d41f46 --- /dev/null +++ b/src/pystencilssfg/lang/cpp/sycl.py @@ -0,0 +1,3 @@ +from .sycl_accessor import SyclAccessor + +accessor = SyclAccessor diff --git a/src/pystencilssfg/lang/cpp/sycl_accessor.py b/src/pystencilssfg/lang/cpp/sycl_accessor.py index f704477b3a92925acf7e318095c8fb67af32cfb2..f01c53d24750dc3b4f0350134e9bccd6f8ea4c26 100644 --- a/src/pystencilssfg/lang/cpp/sycl_accessor.py +++ b/src/pystencilssfg/lang/cpp/sycl_accessor.py @@ -1,36 +1,43 @@ from ...lang import SrcField, IFieldExtraction -from ...ir.source_components import SfgHeaderInclude from pystencils import Field -from pystencils.types import ( - PsType, - PsCustomType, -) +from pystencils.types import UserTypeSpec, create_type -from pystencilssfg.lang.expressions import AugExpr +from ...lang import AugExpr, cpptype, Ref class SyclAccessor(SrcField): + """Represent a + `SYCL Accessor <https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#subsec:accessors>`_. + + .. note:: + + Sycl Accessor do not expose information about strides, so the linearization is done under + the assumption that the underlying memory is contiguous, as descibed + `here <https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#_multi_dimensional_objects_and_linearization>`_ + """ # noqa: E501 + + _template = cpptype("sycl::accessor< {T}, {dims} >", "<sycl/sycl.hpp>") + def __init__( self, - T: PsType, + T: UserTypeSpec, dimensions: int, - reference: bool = False, + ref: bool = False, + const: bool = False, ): - cpp_typestr = T.c_string() - if 3 < dimensions: + T = create_type(T) + if dimensions > 3: raise ValueError("sycl accessors can only have dims 1, 2 or 3") - typestring = ( - f"sycl::accessor< {cpp_typestr}, {dimensions} > {'&' if reference else ''}" - ) - super().__init__(PsCustomType(typestring)) + dtype = self._template(T=T, dims=dimensions, const=const) + if ref: + dtype = Ref(dtype) + + super().__init__(dtype) + self._dim = dimensions self._inner_stride = 1 - @property - def required_includes(self) -> set[SfgHeaderInclude]: - return {SfgHeaderInclude("sycl/sycl.hpp", system_header=True)} - def get_extraction(self) -> IFieldExtraction: accessor = self @@ -66,14 +73,12 @@ class SyclAccessor(SrcField): return Extraction() + @staticmethod + def from_field(field: Field, ref: bool = True): + """Creates a `sycl::accessor &` for a given pystencils field.""" -def sycl_accessor_ref(field: Field): - """Creates a `sycl::accessor &` for a given pystencils field.""" - # Sycl Accessor do not expose information about strides, so the linearization is like here - # https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#_multi_dimensional_objects_and_linearization - - return SyclAccessor( - field.dtype, - field.spatial_dimensions + field.index_dimensions, - reference=True, - ).var(field.name) + return SyclAccessor( + field.dtype, + field.spatial_dimensions + field.index_dimensions, + ref=ref, + ).var(field.name) diff --git a/src/pystencilssfg/lang/expressions.py b/src/pystencilssfg/lang/expressions.py index c8ac0f4cbc95c6af7f5b283852a344c7cc24cb45..ccaf2d1bf3fe224e35be1508f13dfeb3251a84ee 100644 --- a/src/pystencilssfg/lang/expressions.py +++ b/src/pystencilssfg/lang/expressions.py @@ -1,5 +1,5 @@ from __future__ import annotations -from typing import Iterable, TypeAlias, Any, TYPE_CHECKING +from typing import Iterable, TypeAlias, Any from itertools import chain from abc import ABC, abstractmethod @@ -9,10 +9,8 @@ from pystencils import TypedSymbol from pystencils.types import PsType, UserTypeSpec, create_type from ..exceptions import SfgException - -if TYPE_CHECKING: - from ..ir.source_components import SfgHeaderInclude - +from .headers import HeaderFile +from .types import strip_ptr_ref, CppType __all__ = [ "SfgVar", @@ -41,18 +39,10 @@ class SfgVar: self, name: str, dtype: UserTypeSpec, - required_includes: set[SfgHeaderInclude] | None = None, ): - # TODO: Replace `required_includes` by using a property - # Includes attached this way may currently easily be lost during postprocessing, - # since they are not part of `_args` self._name = name self._dtype = create_type(dtype) - self._required_includes = ( - required_includes if required_includes is not None else set() - ) - @property def name(self) -> str: return self._name @@ -73,10 +63,6 @@ class SfgVar: def __hash__(self) -> int: return hash(self._args()) - @property - def required_includes(self) -> set[SfgHeaderInclude]: - return self._required_includes - def name_and_type(self) -> str: return f"{self._name}: {self._dtype}" @@ -88,29 +74,51 @@ class SfgVar: class DependentExpression: + """Wrapper around a C++ expression code string, + annotated with a set of variables and a set of header files this expression depends on. + + Args: + expr: C++ Code string of the expression + depends: Iterable of variables and/or `AugExpr`s from which variable and header dependencies are collected + includes: Iterable of header files which this expression additionally depends on + """ + __match_args__ = ("expr", "depends") - def __init__(self, expr: str, depends: Iterable[SfgVar | AugExpr]): + def __init__( + self, + expr: str, + depends: Iterable[SfgVar | AugExpr], + includes: Iterable[HeaderFile] | None = None, + ): self._expr: str = expr deps: set[SfgVar] = set() + incls: set[HeaderFile] = set(includes) if includes is not None else set() + for obj in depends: if isinstance(obj, AugExpr): deps |= obj.depends + incls |= obj.includes else: deps.add(obj) - self._depends = tuple(deps) + self._depends = frozenset(deps) + self._includes = frozenset(incls) @property def expr(self) -> str: return self._expr @property - def depends(self) -> set[SfgVar]: - return set(self._depends) + def depends(self) -> frozenset[SfgVar]: + return self._depends + + @property + def includes(self) -> frozenset[HeaderFile]: + return self._includes def __hash_contents__(self): - return (self._expr, self._depends) + return (self._expr, self._depends, self._includes) def __eq__(self, other: object): if not isinstance(other, DependentExpression): @@ -125,13 +133,26 @@ class DependentExpression: return self.expr def __add__(self, other: DependentExpression): - return DependentExpression(self.expr + other.expr, self.depends | other.depends) + return DependentExpression( + self.expr + other.expr, + self.depends | other.depends, + self._includes | other._includes, + ) class VarExpr(DependentExpression): def __init__(self, var: SfgVar): self._var = var - super().__init__(var.name, (var,)) + base_type = strip_ptr_ref(var.dtype) + incls: Iterable[HeaderFile] + match base_type: + case CppType(): + incls = base_type.includes + case _: + incls = ( + HeaderFile.parse(header) for header in var.dtype.required_headers + ) + super().__init__(var.name, (var,), incls) @property def variable(self) -> SfgVar: @@ -142,11 +163,35 @@ class AugExpr: """C++ expression augmented with variable dependencies and a type-dependent interface. `AugExpr` is the primary class for modelling C++ expressions in *pystencils-sfg*. - It stores both an expression's code string and the set of variables (`SfgVar`) - the expression depends on. This dependency information is used by the postprocessing - system to infer function parameter lists. + It stores both an expression's code string, + the set of variables (`SfgVar`) the expression depends on, + as well as any headers that must be included for the expression to be evaluated. + This dependency information is used by the composer and postprocessing system + to infer function parameter lists and automatic header inclusions. + + **Construction and Binding** + + Constructing an `AugExpr` is a two-step process comprising *construction* and *binding*. + An `AugExpr` can be constructed with our without an associated data type. + After construction, the `AugExpr` object is still *unbound*; + it does not yet hold any syntax. + + Syntax binding can happen in two ways: - In addition, subclasses of `AugExpr` can mimic C++ APIs by defining factory methods that + - Calling `var <AugExpr.var>` on an unbound `AugExpr` turns it into a *variable* with the given name. + This variable expression takes its set of required header files from the + `required_headers <PsType.required_headers>` field of the data type of the `AugExpr`. + - Using `bind <AugExpr.bind>`, an unbound `AugExpr` can be bound to an arbitrary string + of code. The `bind` method mirrors the interface of `str.format` to combine sub-expressions + and collect their dependencies. + The `format <AugExpr.format>` static method is a wrapper around `bind` for expressions + without a type. + + An `AugExpr` can be bound only once. + + **C++ API Mirroring** + + Subclasses of `AugExpr` can mimic C++ APIs by defining factory methods that build expressions for C++ method calls, etc., from a list of argument expressions. Args: @@ -161,7 +206,7 @@ class AugExpr: self._is_variable = False def var(self, name: str): - v = SfgVar(name, self.get_dtype(), self.required_includes) + v = SfgVar(name, self.get_dtype()) expr = VarExpr(v) return self._bind(expr) @@ -177,18 +222,22 @@ class AugExpr: def bind(self, fmt: str | AugExpr, *deps, **kwdeps): if isinstance(fmt, AugExpr): if bool(deps) or bool(kwdeps): - raise ValueError("Binding to another AugExpr does not permit additional arguments") + raise ValueError( + "Binding to another AugExpr does not permit additional arguments" + ) if fmt._bound is None: raise ValueError("Cannot rebind to unbound AugExpr.") self._bind(fmt._bound) else: dependencies: set[SfgVar] = set() + incls: set[HeaderFile] = set() from pystencils.sympyextensions import is_constant for expr in chain(deps, kwdeps.values()): if isinstance(expr, _ExprLike): dependencies |= depends(expr) + incls |= includes(expr) elif isinstance(expr, sp.Expr) and not is_constant(expr): raise ValueError( f"Cannot parse SymPy expression as C++ expression: {expr}\n" @@ -197,15 +246,9 @@ class AugExpr: ) code = fmt.format(*deps, **kwdeps) - self._bind(DependentExpression(code, dependencies)) + self._bind(DependentExpression(code, dependencies, incls)) return self - def expr(self) -> DependentExpression: - if self._bound is None: - raise SfgException("No syntax bound to this AugExpr.") - - return self._bound - @property def code(self) -> str: if self._bound is None: @@ -213,12 +256,19 @@ class AugExpr: return str(self._bound) @property - def depends(self) -> set[SfgVar]: + def depends(self) -> frozenset[SfgVar]: if self._bound is None: raise SfgException("No syntax bound to this AugExpr.") return self._bound.depends + @property + def includes(self) -> frozenset[HeaderFile]: + if self._bound is None: + raise SfgException("No syntax bound to this AugExpr.") + + return self._bound.includes + @property def dtype(self) -> PsType | None: return self._dtype @@ -238,10 +288,6 @@ class AugExpr: raise SfgException("This expression is not a variable") return self._bound.variable - @property - def required_includes(self) -> set[SfgHeaderInclude]: - return set() - def __str__(self) -> str: if self._bound is None: return "/* [ERROR] unbound AugExpr */" @@ -339,7 +385,33 @@ def depends(expr: ExprLike) -> set[SfgVar]: case TypedSymbol(): return {asvar(expr)} case AugExpr(): - return expr.depends + return set(expr.depends) + case _: + raise ValueError(f"Invalid expression: {expr}") + + +def includes(expr: ExprLike) -> set[HeaderFile]: + """Determine the set of header files an expression depends on. + + Args: + expr: Expression-like object to examine + + Returns: + set[HeaderFile]: Set of headers the expression depends on + + Raises: + ValueError: If the argument was not a valid variable or expression + """ + + match expr: + case SfgVar(_, dtype): + return set(HeaderFile.parse(h) for h in dtype.required_headers) + case TypedSymbol(): + return includes(asvar(expr)) + case str(): + return set() + case AugExpr(): + return set(expr.includes) case _: raise ValueError(f"Invalid expression: {expr}") @@ -350,15 +422,15 @@ class IFieldExtraction(ABC): @abstractmethod def ptr(self) -> AugExpr: - pass + ... @abstractmethod def size(self, coordinate: int) -> AugExpr | None: - pass + ... @abstractmethod def stride(self, coordinate: int) -> AugExpr | None: - pass + ... class SrcField(AugExpr): @@ -370,7 +442,7 @@ class SrcField(AugExpr): @abstractmethod def get_extraction(self) -> IFieldExtraction: - pass + ... class SrcVector(AugExpr, ABC): @@ -382,4 +454,4 @@ class SrcVector(AugExpr, ABC): @abstractmethod def extract_component(self, coordinate: int) -> AugExpr: - pass + ... diff --git a/src/pystencilssfg/lang/headers.py b/src/pystencilssfg/lang/headers.py new file mode 100644 index 0000000000000000000000000000000000000000..fdb8f17be3ddbe177994c67099cebeaeb719b67e --- /dev/null +++ b/src/pystencilssfg/lang/headers.py @@ -0,0 +1,31 @@ +from __future__ import annotations +from dataclasses import dataclass + + +@dataclass(frozen=True) +class HeaderFile: + """Represents a C++ header file.""" + + filepath: str + """(Relative) path of this header file""" + + system_header: bool = False + """Whether or not this is a system header.""" + + def __str__(self) -> str: + if self.system_header: + return f"<{self.filepath}>" + else: + return self.filepath + + @staticmethod + def parse(header: str | HeaderFile): + if isinstance(header, HeaderFile): + return header + + system_header = False + if header.startswith("<") and header.endswith(">"): + header = header[1:-1] + system_header = True + + return HeaderFile(header, system_header=system_header) diff --git a/src/pystencilssfg/lang/types.py b/src/pystencilssfg/lang/types.py index 084f1d529a020b9796aeb82e208579f6f1aa5724..b3a634fbb63bb93d6c8e504030590df477cd200d 100644 --- a/src/pystencilssfg/lang/types.py +++ b/src/pystencilssfg/lang/types.py @@ -1,5 +1,65 @@ -from typing import Any -from pystencils.types import PsType, PsPointerType +from typing import Any, Iterable +from abc import ABC +from pystencils.types import PsType, PsPointerType, PsCustomType +from .headers import HeaderFile + + +class VoidType(PsType): + """C++ void type.""" + + def __init__(self, const: bool = False): + super().__init__(False) + + def __args__(self) -> tuple[Any, ...]: + return () + + def c_string(self) -> str: + return "void" + + def __repr__(self) -> str: + return "VoidType()" + + +void = VoidType() + + +class CppType(PsCustomType, ABC): + includes: frozenset[HeaderFile] + + @property + def required_headers(self) -> set[str]: + return set(str(h) for h in self.includes) + + +def cpptype(typestr: str, include: str | HeaderFile | Iterable[str | HeaderFile] = ()): + headers: list[str | HeaderFile] + + if isinstance(include, (str, HeaderFile)): + headers = [ + include, + ] + else: + headers = list(include) + + def _fixarg(template_arg): + if isinstance(template_arg, PsType): + return template_arg.c_string() + else: + return str(template_arg) + + class TypeClass(CppType): + includes = frozenset(HeaderFile.parse(h) for h in headers) + + def __init__(self, *template_args, const: bool = False, **template_kwargs): + template_args = tuple(_fixarg(arg) for arg in template_args) + template_kwargs = { + key: _fixarg(value) for key, value in template_kwargs.items() + } + + name = typestr.format(*template_args, **template_kwargs) + super().__init__(name, const) + + return TypeClass class Ref(PsType): diff --git a/tests/generator_scripts/.gitignore b/tests/generator_scripts/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..73fb7d9cb9955780f7d2d944aaa158171814fcb4 --- /dev/null +++ b/tests/generator_scripts/.gitignore @@ -0,0 +1,2 @@ +deps/mdspan-* +*.lock \ No newline at end of file diff --git a/tests/generator_scripts/README.md b/tests/generator_scripts/README.md new file mode 100644 index 0000000000000000000000000000000000000000..185e2703e2206a0c1d6377effbf6c9961cae83a4 --- /dev/null +++ b/tests/generator_scripts/README.md @@ -0,0 +1,176 @@ +# Generator Script Test Suite + +This directory contains the generator script test suite of pystencils-sfg. +Here, the code generation pipeline of the SFG is tested in full by running +and evaluating the output of generator scripts. +This has proven much more effective than trying to construct fine-grained +unit tests for the `composer`, `ir` and `emission` modules. + +## Structure + +The `pystencils-sfg/tests/generator-scripts` directory contains these subfolders and files: + - `deps`: Dependencies of the test suite, e.g. std::mdspan + - `source`: Generator scripts, their configuration and test harnesses + - `index.yaml`: Test suite index + - `test_generator_scripts.py`: Actual test suite code, run by pytest + +## Registering Tests + +A generator script test comprises at least a generator script `<name>.py` in the `source` directory, +and an associated entry in `index.yaml`. +That entry may define various options for the testing run of that script. +A test may optionally define a C++ harness program called `<name>.harness.cpp` in the `source` directory, +against which the generated code will be tested. + +### Creating a New Test + +At its top level, the test index file `index.yaml` is a dictionary mapping test names to their parameters. +After creating the `<name>.py` generator script, we register it by adding an empty entry: + +```yaml +# somewhere in index.yaml + +<name>: + # params (might be empty) +``` + +This will allow the test suite to discover `<name>.py` and add an associated test to its `pytest` test set. +The test can be parametrized using the parameters listed in the parameter reference below. + +### Test Execution Flow + +The above empty test definition already leads to the following execution flow: + - The generator script is executed and its output placed in a temporary directory. + If the script fails, so does the test. + - The set of output files is checked against the expected file set. + By default, scripts are expected to emit one `.hpp` file and one `.cpp` file, + but the expected files can be affected with test parameters as explained below. + - If any generated files are detected as 'compilable' from their extensions (candidates are `.cpp`, `.cxx`, and`.c++`). + the test suite will attempt to compile them using default settings + (currently `g++ -std=c++20`, with the `<experimental/mdspan>` header in scope). + If compilation fails, the test fails. + - If a test harness (`<name>.harness.cpp`) is found in the `source` folder, it will be compiled and linked as an executable + against the generated files. + The harness executable is then executed. + If compilation fails or execution yields a return code other than `0`, the test fails. + +If all steps run without errors, the test succeeds. + +### Writing a Test Harness + +The most important requirement placed on our code generator is that it produces +functionally correct code that adheres exactly to its input specification. +For one, all generated code must be compilable using an appropriate compiler, +so compiling it (with strict treatment of warnings) as part of the test is a sure way of +checking its syntactical correctness. +Its semantical correctness can be further ensured by providing a C++ test harness. +This test harness can check the semantics of the generated code both statically +(using compile-time assertions, combined with concepts or type traits) +and dynamically (by executing the generated code and checking its output). + +Each generator script registered at the test suite can have one test harness named `<name>.harness.cpp` +in the `source` folder. That test harness should `#include` any generated header files +(the test suite ensures the generated files are on the compiler's include path). + +Since it will be compiled to an executable, the test harness must also define a `main` function +which should call any dynamic functional tests of the generated code. +If any dynamic test fails, the harness application must terminate with a nonzero error code. + +## Test Index (`index.yaml`) Parameter Reference + +Each entry in `index.yaml` must be a dictionary. +The test suite parses the following (groups of) parameters: + +#### `sfg-args` + +SFG-related command-line parameters passed to the generator script. +These may be: +- `output-mode`: Define the output mode, can be either `standalone`, `inline` or `header-only`. +If `header-only` is specified, the set of expected output files is reduced to `{".hpp"}`. +- `file-extensions`: List of file extensions for the output files of the generator script. +If specified, these are taken as the expected output files by the test suite. +- `config-module`: Path to a config module, relative to `source/`. +The Python file referred to by this option will be passed as a configuration module to the generator script. + +#### `extra-args` +List of additional command line parameters passed to the script. + +#### `expected-output` + +List of file extensions that are expected to be produced by the generator script. +Overrides any other source of expected file extensions; +use this if file extensions are determined by inline configuration or the configuration module. + +#### `expect-failure` + +Boolean indicating whether the script is expected to fail. +If set to `True`, the test fails if the script runs successfully. + +#### `expect-code` + +Dictionary mapping file extensions to a list of string patterns +that are expected to be generated in the respective files. +These patterns may be: +- A plain string: In this case, that string must be contained verbatim in the generated code +- A dictionary defining at least the `regex` key containing a regular expressions, + and some options affecting its matching. + +**Example: Plain String** +This example requires that the generated `hpp` file contains the inclusion of `iostream` verbatim: + +```yaml +MyTest: + expect-code: + hpp: + - "#include <iostream>" +``` + +**Example: Regular Expression** +This example requires a type alias for an `std::mdspan` instance be defined in the header file, +but does not care about the exact extents, or number of spaces used inside the template parameter list: + +```yaml +MyTest: + expect-code: + hpp: + - regex: using\sfield_t\s=\sstd::mdspan<\s*float,\s*std::extents<.*>\s*> +``` + +In the regex example, the pattern is a dictionary with the single key `regex`. +Regex matching can be configured by adding additional keys: +- `count`: How often the regex should match; default is `1` +- `strip-whitespace`: Set to `true` to have the test suite remove any whitespace from the regex string. + Use this if you want to break your long regular expression across several lines. Default is `false`. + +**Example: Multiline Regex** +This example is the same as above, but using folded block style (see [yaml-multiline.info](https://yaml-multiline.info/)) +to line-break the regex: + +```yaml +MyTest: + expect-code: + hpp: + - regex: >- + using\sfield_t\s= + \sstd::mdspan<\s* + float,\s* + std::extents<.*> + \s*> + - strip-whitespace: true +``` + +#### `compile` + +Options affecting compilation of the generated files and the test harness. +Possible options are: +- `cxx`: Executable of the C++ compiler; default is `g++` +- `cxx-flags`: List of arguments to the C++ compiler; default is `["-std=c++20", "-Wall", "-Werror"]` +- `link-flags`: List of arguments for the linker; default is `[]` +- `skip-if-not-found`: If set to `true` and the compiler specified in `cxx` cannot be found, + skip compilation and harness execution. Otherwise, fail the test. + +## Dependencies + +The `deps` folder includes any vendored dependencies required by generated code. +At the moment, this includes the reference implementation of `std::mdspan` +provided by the Kokkos group [here](https://github.com/kokkos/mdspan). diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/compressed_pair.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/compressed_pair.hpp deleted file mode 100644 index 25389a2fa5e7be9c2f3bdb35d0a5ff4a746b027a..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/compressed_pair.hpp +++ /dev/null @@ -1,195 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER -#pragma once - -#include "macros.hpp" -#include "trait_backports.hpp" - -#if !defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) -# include "no_unique_address.hpp" -#endif - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -namespace detail { - -// For no unique address emulation, this is the case taken when neither are empty. -// For real `[[no_unique_address]]`, this case is always taken. -template <class _T1, class _T2, class _Enable = void> struct __compressed_pair { - _MDSPAN_NO_UNIQUE_ADDRESS _T1 __t1_val{}; - _MDSPAN_NO_UNIQUE_ADDRESS _T2 __t2_val{}; - MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T1 &__first() noexcept { return __t1_val; } - MDSPAN_FORCE_INLINE_FUNCTION constexpr _T1 const &__first() const noexcept { - return __t1_val; - } - MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T2 &__second() noexcept { return __t2_val; } - MDSPAN_FORCE_INLINE_FUNCTION constexpr _T2 const &__second() const noexcept { - return __t2_val; - } - - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr __compressed_pair() = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr __compressed_pair(__compressed_pair const &) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr __compressed_pair(__compressed_pair &&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair & - operator=(__compressed_pair const &) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair & - operator=(__compressed_pair &&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - ~__compressed_pair() = default; - template <class _T1Like, class _T2Like> - MDSPAN_INLINE_FUNCTION constexpr __compressed_pair(_T1Like &&__t1, _T2Like &&__t2) - : __t1_val((_T1Like &&) __t1), __t2_val((_T2Like &&) __t2) {} -}; - -#if !defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - -// First empty. -template <class _T1, class _T2> -struct __compressed_pair< - _T1, _T2, - std::enable_if_t<_MDSPAN_TRAIT(std::is_empty, _T1) && !_MDSPAN_TRAIT(std::is_empty, _T2)>> - : private _T1 { - _T2 __t2_val{}; - MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T1 &__first() noexcept { - return *static_cast<_T1 *>(this); - } - MDSPAN_FORCE_INLINE_FUNCTION constexpr _T1 const &__first() const noexcept { - return *static_cast<_T1 const *>(this); - } - MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T2 &__second() noexcept { return __t2_val; } - MDSPAN_FORCE_INLINE_FUNCTION constexpr _T2 const &__second() const noexcept { - return __t2_val; - } - - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr __compressed_pair() = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr __compressed_pair(__compressed_pair const &) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr __compressed_pair(__compressed_pair &&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair & - operator=(__compressed_pair const &) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair & - operator=(__compressed_pair &&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - ~__compressed_pair() = default; - template <class _T1Like, class _T2Like> - MDSPAN_INLINE_FUNCTION constexpr __compressed_pair(_T1Like &&__t1, _T2Like &&__t2) - : _T1((_T1Like &&) __t1), __t2_val((_T2Like &&) __t2) {} -}; - -// Second empty. -template <class _T1, class _T2> -struct __compressed_pair< - _T1, _T2, - std::enable_if_t<!_MDSPAN_TRAIT(std::is_empty, _T1) && _MDSPAN_TRAIT(std::is_empty, _T2)>> - : private _T2 { - _T1 __t1_val{}; - MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T1 &__first() noexcept { return __t1_val; } - MDSPAN_FORCE_INLINE_FUNCTION constexpr _T1 const &__first() const noexcept { - return __t1_val; - } - MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T2 &__second() noexcept { - return *static_cast<_T2 *>(this); - } - MDSPAN_FORCE_INLINE_FUNCTION constexpr _T2 const &__second() const noexcept { - return *static_cast<_T2 const *>(this); - } - - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr __compressed_pair() = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr __compressed_pair(__compressed_pair const &) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr __compressed_pair(__compressed_pair &&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair & - operator=(__compressed_pair const &) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair & - operator=(__compressed_pair &&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - ~__compressed_pair() = default; - - template <class _T1Like, class _T2Like> - MDSPAN_INLINE_FUNCTION constexpr __compressed_pair(_T1Like &&__t1, _T2Like &&__t2) - : _T2((_T2Like &&) __t2), __t1_val((_T1Like &&) __t1) {} -}; - -// Both empty. -template <class _T1, class _T2> -struct __compressed_pair< - _T1, _T2, - std::enable_if_t<_MDSPAN_TRAIT(std::is_empty, _T1) && _MDSPAN_TRAIT(std::is_empty, _T2)>> - // We need to use the __no_unique_address_emulation wrapper here to avoid - // base class ambiguities. -#ifdef _MDSPAN_COMPILER_MSVC -// MSVC doesn't allow you to access public static member functions of a type -// when you *happen* to privately inherit from that type. - : protected __no_unique_address_emulation<_T1, 0>, - protected __no_unique_address_emulation<_T2, 1> -#else - : private __no_unique_address_emulation<_T1, 0>, - private __no_unique_address_emulation<_T2, 1> -#endif -{ - using __first_base_t = __no_unique_address_emulation<_T1, 0>; - using __second_base_t = __no_unique_address_emulation<_T2, 1>; - - MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T1 &__first() noexcept { - return this->__first_base_t::__ref(); - } - MDSPAN_FORCE_INLINE_FUNCTION constexpr _T1 const &__first() const noexcept { - return this->__first_base_t::__ref(); - } - MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T2 &__second() noexcept { - return this->__second_base_t::__ref(); - } - MDSPAN_FORCE_INLINE_FUNCTION constexpr _T2 const &__second() const noexcept { - return this->__second_base_t::__ref(); - } - - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr __compressed_pair() = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr __compressed_pair(__compressed_pair const &) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr __compressed_pair(__compressed_pair &&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair & - operator=(__compressed_pair const &) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - _MDSPAN_CONSTEXPR_14_DEFAULTED __compressed_pair & - operator=(__compressed_pair &&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - ~__compressed_pair() = default; - template <class _T1Like, class _T2Like> - MDSPAN_INLINE_FUNCTION constexpr __compressed_pair(_T1Like &&__t1, _T2Like &&__t2) noexcept - : __first_base_t(_T1((_T1Like &&) __t1)), - __second_base_t(_T2((_T2Like &&) __t2)) - { } -}; - -#endif // !defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - -} // end namespace detail -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/config.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/config.hpp deleted file mode 100644 index 24166462e7abd5e96a941b8ba9f5d302369d07c7..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/config.hpp +++ /dev/null @@ -1,281 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER -#pragma once - -#ifndef __has_include -# define __has_include(x) 0 -#endif - -#if __has_include(<version>) -# include <version> -#else -# include <type_traits> -# include <utility> -#endif - -#ifdef _MSVC_LANG -#define _MDSPAN_CPLUSPLUS _MSVC_LANG -#else -#define _MDSPAN_CPLUSPLUS __cplusplus -#endif - -#define MDSPAN_CXX_STD_14 201402L -#define MDSPAN_CXX_STD_17 201703L -#define MDSPAN_CXX_STD_20 202002L -// Note GCC has not updated this in version 13 -#ifdef __clang__ -#define MDSPAN_CXX_STD_23 202302L -#else -#define MDSPAN_CXX_STD_23 202100L -#endif - -#define MDSPAN_HAS_CXX_14 (_MDSPAN_CPLUSPLUS >= MDSPAN_CXX_STD_14) -#define MDSPAN_HAS_CXX_17 (_MDSPAN_CPLUSPLUS >= MDSPAN_CXX_STD_17) -#define MDSPAN_HAS_CXX_20 (_MDSPAN_CPLUSPLUS >= MDSPAN_CXX_STD_20) -#define MDSPAN_HAS_CXX_23 (_MDSPAN_CPLUSPLUS >= MDSPAN_CXX_STD_23) - -static_assert(_MDSPAN_CPLUSPLUS >= MDSPAN_CXX_STD_14, "mdspan requires C++14 or later."); - -#ifndef _MDSPAN_COMPILER_CLANG -# if defined(__clang__) -# define _MDSPAN_COMPILER_CLANG __clang__ -# endif -#endif - -#if !defined(_MDSPAN_COMPILER_MSVC) && !defined(_MDSPAN_COMPILER_MSVC_CLANG) -# if defined(_MSC_VER) -# if !defined(_MDSPAN_COMPILER_CLANG) -# define _MDSPAN_COMPILER_MSVC _MSC_VER -# else -# define _MDSPAN_COMPILER_MSVC_CLANG _MSC_VER -# endif -# endif -#endif - -#ifndef _MDSPAN_COMPILER_INTEL -# ifdef __INTEL_COMPILER -# define _MDSPAN_COMPILER_INTEL __INTEL_COMPILER -# endif -#endif - -#ifndef _MDSPAN_COMPILER_APPLECLANG -# ifdef __apple_build_version__ -# define _MDSPAN_COMPILER_APPLECLANG __apple_build_version__ -# endif -#endif - -#ifndef _MDSPAN_HAS_CUDA -# if defined(__CUDACC__) -# define _MDSPAN_HAS_CUDA __CUDACC__ -# endif -#endif - -#ifndef _MDSPAN_HAS_HIP -# if defined(__HIPCC__) -# define _MDSPAN_HAS_HIP __HIPCC__ -# endif -#endif - -#ifndef _MDSPAN_HAS_SYCL -# if defined(SYCL_LANGUAGE_VERSION) -# define _MDSPAN_HAS_SYCL SYCL_LANGUAGE_VERSION -# endif -#endif - -#ifndef __has_cpp_attribute -# define __has_cpp_attribute(x) 0 -#endif - -#ifndef _MDSPAN_PRESERVE_STANDARD_LAYOUT -// Preserve standard layout by default, but we're not removing the old version -// that turns this off until we're sure this doesn't have an unreasonable cost -// to the compiler or optimizer. -# define _MDSPAN_PRESERVE_STANDARD_LAYOUT 1 -#endif - -#if !defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) -# if ((__has_cpp_attribute(no_unique_address) >= 201803L) && \ - (!defined(__NVCC__) || MDSPAN_HAS_CXX_20) && \ - (!defined(_MDSPAN_COMPILER_MSVC) || MDSPAN_HAS_CXX_20)) -# define _MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS 1 -# define _MDSPAN_NO_UNIQUE_ADDRESS [[no_unique_address]] -# else -# define _MDSPAN_NO_UNIQUE_ADDRESS -# endif -#endif - -// NVCC older than 11.6 chokes on the no-unique-address-emulation -// so just pretend to use it (to avoid the full blown EBO workaround -// which NVCC also doesn't like ...), and leave the macro empty -#ifndef _MDSPAN_NO_UNIQUE_ADDRESS -# if defined(__NVCC__) -# define _MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS 1 -# define _MDSPAN_USE_FAKE_ATTRIBUTE_NO_UNIQUE_ADDRESS -# endif -# define _MDSPAN_NO_UNIQUE_ADDRESS -#endif - -// AMDs HIP compiler seems to have issues with concepts -// it pretends concepts exist, but doesn't ship <concept> -#ifndef __HIPCC__ -#ifndef _MDSPAN_USE_CONCEPTS -# if defined(__cpp_concepts) && __cpp_concepts >= 201507L -# define _MDSPAN_USE_CONCEPTS 1 -# endif -#endif -#endif - -#ifndef _MDSPAN_USE_FOLD_EXPRESSIONS -# if (defined(__cpp_fold_expressions) && __cpp_fold_expressions >= 201603L) \ - || (!defined(__cpp_fold_expressions) && MDSPAN_HAS_CXX_17) -# define _MDSPAN_USE_FOLD_EXPRESSIONS 1 -# endif -#endif - -#ifndef _MDSPAN_USE_INLINE_VARIABLES -# if defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L \ - || (!defined(__cpp_inline_variables) && MDSPAN_HAS_CXX_17) -# define _MDSPAN_USE_INLINE_VARIABLES 1 -# endif -#endif - -#ifndef _MDSPAN_NEEDS_TRAIT_VARIABLE_TEMPLATE_BACKPORTS -# if (!(defined(__cpp_lib_type_trait_variable_templates) && __cpp_lib_type_trait_variable_templates >= 201510L) \ - || !MDSPAN_HAS_CXX_17) -# if !(defined(_MDSPAN_COMPILER_APPLECLANG) && MDSPAN_HAS_CXX_17) -# define _MDSPAN_NEEDS_TRAIT_VARIABLE_TEMPLATE_BACKPORTS 1 -# endif -# endif -#endif - -#ifndef _MDSPAN_USE_VARIABLE_TEMPLATES -# if (defined(__cpp_variable_templates) && __cpp_variable_templates >= 201304 && MDSPAN_HAS_CXX_17) \ - || (!defined(__cpp_variable_templates) && MDSPAN_HAS_CXX_17) -# define _MDSPAN_USE_VARIABLE_TEMPLATES 1 -# endif -#endif // _MDSPAN_USE_VARIABLE_TEMPLATES - -#ifndef _MDSPAN_USE_CONSTEXPR_14 -# if (defined(__cpp_constexpr) && __cpp_constexpr >= 201304) \ - || (!defined(__cpp_constexpr) && MDSPAN_HAS_CXX_14) \ - && (!(defined(__INTEL_COMPILER) && __INTEL_COMPILER <= 1700)) -# define _MDSPAN_USE_CONSTEXPR_14 1 -# endif -#endif - -#ifndef _MDSPAN_USE_INTEGER_SEQUENCE -# if defined(_MDSPAN_COMPILER_MSVC) -# if (defined(__cpp_lib_integer_sequence) && __cpp_lib_integer_sequence >= 201304) -# define _MDSPAN_USE_INTEGER_SEQUENCE 1 -# endif -# endif -#endif -#ifndef _MDSPAN_USE_INTEGER_SEQUENCE -# if (defined(__cpp_lib_integer_sequence) && __cpp_lib_integer_sequence >= 201304) \ - || (!defined(__cpp_lib_integer_sequence) && MDSPAN_HAS_CXX_14) \ - /* as far as I can tell, libc++ seems to think this is a C++11 feature... */ \ - || (defined(__GLIBCXX__) && __GLIBCXX__ > 20150422 && __GNUC__ < 5 && !defined(__INTEL_CXX11_MODE__)) - // several compilers lie about integer_sequence working properly unless the C++14 standard is used -# define _MDSPAN_USE_INTEGER_SEQUENCE 1 -# elif defined(_MDSPAN_COMPILER_APPLECLANG) && MDSPAN_HAS_CXX_14 - // appleclang seems to be missing the __cpp_lib_... macros, but doesn't seem to lie about C++14 making - // integer_sequence work -# define _MDSPAN_USE_INTEGER_SEQUENCE 1 -# endif -#endif - -#ifndef _MDSPAN_USE_RETURN_TYPE_DEDUCTION -# if (defined(__cpp_return_type_deduction) && __cpp_return_type_deduction >= 201304) \ - || (!defined(__cpp_return_type_deduction) && MDSPAN_HAS_CXX_14) -# define _MDSPAN_USE_RETURN_TYPE_DEDUCTION 1 -# endif -#endif - -#ifndef _MDSPAN_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION -# if (!defined(__NVCC__) || (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__ * 10 >= 1170)) && \ - ((defined(__cpp_deduction_guides) && __cpp_deduction_guides >= 201703) || \ - (!defined(__cpp_deduction_guides) && MDSPAN_HAS_CXX_17)) -# define _MDSPAN_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION 1 -# endif -#endif - -#ifndef _MDSPAN_USE_STANDARD_TRAIT_ALIASES -# if (defined(__cpp_lib_transformation_trait_aliases) && __cpp_lib_transformation_trait_aliases >= 201304) \ - || (!defined(__cpp_lib_transformation_trait_aliases) && MDSPAN_HAS_CXX_14) -# define _MDSPAN_USE_STANDARD_TRAIT_ALIASES 1 -# elif defined(_MDSPAN_COMPILER_APPLECLANG) && MDSPAN_HAS_CXX_14 - // appleclang seems to be missing the __cpp_lib_... macros, but doesn't seem to lie about C++14 -# define _MDSPAN_USE_STANDARD_TRAIT_ALIASES 1 -# endif -#endif - -#ifndef _MDSPAN_DEFAULTED_CONSTRUCTORS_INHERITANCE_WORKAROUND -# ifdef __GNUC__ -# if __GNUC__ < 9 -# define _MDSPAN_DEFAULTED_CONSTRUCTORS_INHERITANCE_WORKAROUND 1 -# endif -# endif -#endif - -#ifndef MDSPAN_CONDITIONAL_EXPLICIT -# if MDSPAN_HAS_CXX_20 -# define MDSPAN_CONDITIONAL_EXPLICIT(COND) explicit(COND) -# else -# define MDSPAN_CONDITIONAL_EXPLICIT(COND) -# endif -#endif - -#ifndef MDSPAN_USE_BRACKET_OPERATOR -# if defined(__cpp_multidimensional_subscript) -# define MDSPAN_USE_BRACKET_OPERATOR 1 -# else -# define MDSPAN_USE_BRACKET_OPERATOR 0 -# endif -#endif - -#ifndef MDSPAN_USE_PAREN_OPERATOR -# if !MDSPAN_USE_BRACKET_OPERATOR -# define MDSPAN_USE_PAREN_OPERATOR 1 -# else -# define MDSPAN_USE_PAREN_OPERATOR 0 -# endif -#endif - -#if MDSPAN_USE_BRACKET_OPERATOR -# define __MDSPAN_OP(mds,...) mds[__VA_ARGS__] -// Corentins demo compiler for subscript chokes on empty [] call, -// though I believe the proposal supports it? -#ifdef MDSPAN_NO_EMPTY_BRACKET_OPERATOR -# define __MDSPAN_OP0(mds) mds.accessor().access(mds.data_handle(),0) -#else -# define __MDSPAN_OP0(mds) mds[] -#endif -# define __MDSPAN_OP1(mds, a) mds[a] -# define __MDSPAN_OP2(mds, a, b) mds[a,b] -# define __MDSPAN_OP3(mds, a, b, c) mds[a,b,c] -# define __MDSPAN_OP4(mds, a, b, c, d) mds[a,b,c,d] -# define __MDSPAN_OP5(mds, a, b, c, d, e) mds[a,b,c,d,e] -# define __MDSPAN_OP6(mds, a, b, c, d, e, f) mds[a,b,c,d,e,f] -#else -# define __MDSPAN_OP(mds,...) mds(__VA_ARGS__) -# define __MDSPAN_OP0(mds) mds() -# define __MDSPAN_OP1(mds, a) mds(a) -# define __MDSPAN_OP2(mds, a, b) mds(a,b) -# define __MDSPAN_OP3(mds, a, b, c) mds(a,b,c) -# define __MDSPAN_OP4(mds, a, b, c, d) mds(a,b,c,d) -# define __MDSPAN_OP5(mds, a, b, c, d, e) mds(a,b,c,d,e) -# define __MDSPAN_OP6(mds, a, b, c, d, e, f) mds(a,b,c,d,e,f) -#endif diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/default_accessor.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/default_accessor.hpp deleted file mode 100644 index ea0f537b2fe191ace9c6f5271d5b7331e172a4fd..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/default_accessor.hpp +++ /dev/null @@ -1,56 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER -#pragma once - -#include "macros.hpp" - -#include <cstddef> // size_t - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { - -template <class ElementType> -struct default_accessor { - - using offset_policy = default_accessor; - using element_type = ElementType; - using reference = ElementType&; - using data_handle_type = ElementType*; - - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr default_accessor() noexcept = default; - - MDSPAN_TEMPLATE_REQUIRES( - class OtherElementType, - /* requires */ ( - _MDSPAN_TRAIT(std::is_convertible, OtherElementType(*)[], element_type(*)[]) - ) - ) - MDSPAN_INLINE_FUNCTION - constexpr default_accessor(default_accessor<OtherElementType>) noexcept {} - - MDSPAN_INLINE_FUNCTION - constexpr data_handle_type - offset(data_handle_type p, size_t i) const noexcept { - return p + i; - } - - MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference access(data_handle_type p, size_t i) const noexcept { - return p[i]; - } - -}; - -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/dynamic_extent.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/dynamic_extent.hpp deleted file mode 100644 index 2e29da13d6adfd1107fe7ea3ff022bfcf376f189..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/dynamic_extent.hpp +++ /dev/null @@ -1,35 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER -#pragma once - -#include "macros.hpp" - -#if defined(__cpp_lib_span) -#include <span> -#endif - -#include <cstddef> // size_t -#include <limits> // numeric_limits - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -#if defined(__cpp_lib_span) -using std::dynamic_extent; -#else -_MDSPAN_INLINE_VARIABLE constexpr auto dynamic_extent = std::numeric_limits<size_t>::max(); -#endif -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE - -//============================================================================================================== diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/extents.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/extents.hpp deleted file mode 100644 index 98a57e34e649bb6e026df34af073531883a3abbf..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/extents.hpp +++ /dev/null @@ -1,691 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER - -#pragma once -#include "dynamic_extent.hpp" -#include "utility.hpp" - -#ifdef __cpp_lib_span -#include <span> -#endif -#include <array> -#include <type_traits> - -#include <cassert> -#include <cinttypes> - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -namespace detail { - -// Function used to check compatibility of extents in converting constructor -// can't be a private member function for some reason. -template <size_t... Extents, size_t... OtherExtents> -static constexpr std::integral_constant<bool, false> __check_compatible_extents( - std::integral_constant<bool, false>, - std::integer_sequence<size_t, Extents...>, - std::integer_sequence<size_t, OtherExtents...>) noexcept { - return {}; -} - -// This helper prevents ICE's on MSVC. -template <size_t Lhs, size_t Rhs> -struct __compare_extent_compatible : std::integral_constant<bool, - Lhs == dynamic_extent || - Rhs == dynamic_extent || - Lhs == Rhs> -{}; - -template <size_t... Extents, size_t... OtherExtents> -static constexpr std::integral_constant< - bool, _MDSPAN_FOLD_AND(__compare_extent_compatible<Extents, OtherExtents>::value)> -__check_compatible_extents( - std::integral_constant<bool, true>, - std::integer_sequence<size_t, Extents...>, - std::integer_sequence<size_t, OtherExtents...>) noexcept { - return {}; -} - -template<class IndexType, class ... Arguments> -MDSPAN_INLINE_FUNCTION -static constexpr bool are_valid_indices() { - return - _MDSPAN_FOLD_AND(std::is_convertible<Arguments, IndexType>::value) && - _MDSPAN_FOLD_AND(std::is_nothrow_constructible<IndexType, Arguments>::value); -} - -// ------------------------------------------------------------------ -// ------------ static_array ---------------------------------------- -// ------------------------------------------------------------------ - -// array like class which provides an array of static values with get -// function and operator []. - -// Implementation of Static Array with recursive implementation of get. -template <size_t R, class T, T... Extents> struct static_array_impl; - -template <size_t R, class T, T FirstExt, T... Extents> -struct static_array_impl<R, T, FirstExt, Extents...> { - MDSPAN_INLINE_FUNCTION - constexpr static T get(size_t r) { - if (r == R) - return FirstExt; - else - return static_array_impl<R + 1, T, Extents...>::get(r); - } - template <size_t r> MDSPAN_INLINE_FUNCTION constexpr static T get() { -#if MDSPAN_HAS_CXX_17 - if constexpr (r == R) - return FirstExt; - else - return static_array_impl<R + 1, T, Extents...>::template get<r>(); -#else - get(r); -#endif - } -}; - -// End the recursion -template <size_t R, class T, T FirstExt> -struct static_array_impl<R, T, FirstExt> { - MDSPAN_INLINE_FUNCTION - constexpr static T get(size_t) { return FirstExt; } - template <size_t> MDSPAN_INLINE_FUNCTION constexpr static T get() { - return FirstExt; - } -}; - -// Don't start recursion if size 0 -template <class T> struct static_array_impl<0, T> { - MDSPAN_INLINE_FUNCTION - constexpr static T get(size_t) { return T(); } - template <size_t> MDSPAN_INLINE_FUNCTION constexpr static T get() { - return T(); - } -}; - -// Static array, provides get<r>(), get(r) and operator[r] -template <class T, T... Values> struct static_array: - public static_array_impl<0, T, Values...> { - -public: - using value_type = T; - - MDSPAN_INLINE_FUNCTION - constexpr static size_t size() { return sizeof...(Values); } -}; - - -// ------------------------------------------------------------------ -// ------------ index_sequence_scan --------------------------------- -// ------------------------------------------------------------------ - -// index_sequence_scan takes compile time values and provides get(r) -// and get<r>() which return the sum of the first r-1 values. - -// Recursive implementation for get -template <size_t R, size_t... Values> struct index_sequence_scan_impl; - -template <size_t R, size_t FirstVal, size_t... Values> -struct index_sequence_scan_impl<R, FirstVal, Values...> { - MDSPAN_INLINE_FUNCTION - constexpr static size_t get(size_t r) { - if (r > R) - return FirstVal + index_sequence_scan_impl<R + 1, Values...>::get(r); - else - return 0; - } -}; - -template <size_t R, size_t FirstVal> -struct index_sequence_scan_impl<R, FirstVal> { -#if defined(__NVCC__) || defined(__NVCOMPILER) || \ - defined(_MDSPAN_COMPILER_INTEL) - // NVCC warns about pointless comparison with 0 for R==0 and r being const - // evaluatable and also 0. - MDSPAN_INLINE_FUNCTION - constexpr static size_t get(size_t r) { - return static_cast<int64_t>(R) > static_cast<int64_t>(r) ? FirstVal : 0; - } -#else - MDSPAN_INLINE_FUNCTION - constexpr static size_t get(size_t r) { return R > r ? FirstVal : 0; } -#endif -}; -template <> struct index_sequence_scan_impl<0> { - MDSPAN_INLINE_FUNCTION - constexpr static size_t get(size_t) { return 0; } -}; - -// ------------------------------------------------------------------ -// ------------ possibly_empty_array ------------------------------- -// ------------------------------------------------------------------ - -// array like class which provides get function and operator [], and -// has a specialization for the size 0 case. -// This is needed to make the maybe_static_array be truly empty, for -// all static values. - -template <class T, size_t N> struct possibly_empty_array { - T vals[N]{}; - MDSPAN_INLINE_FUNCTION - constexpr T &operator[](size_t r) { return vals[r]; } - MDSPAN_INLINE_FUNCTION - constexpr const T &operator[](size_t r) const { return vals[r]; } -}; - -template <class T> struct possibly_empty_array<T, 0> { - MDSPAN_INLINE_FUNCTION - constexpr T operator[](size_t) { return T(); } - MDSPAN_INLINE_FUNCTION - constexpr const T operator[](size_t) const { return T(); } -}; - -// ------------------------------------------------------------------ -// ------------ maybe_static_array ---------------------------------- -// ------------------------------------------------------------------ - -// array like class which has a mix of static and runtime values but -// only stores the runtime values. -// The type of the static and the runtime values can be different. -// The position of a dynamic value is indicated through a tag value. -template <class TDynamic, class TStatic, TStatic dyn_tag, TStatic... Values> -struct maybe_static_array { - - static_assert(std::is_convertible<TStatic, TDynamic>::value, "maybe_static_array: TStatic must be convertible to TDynamic"); - static_assert(std::is_convertible<TDynamic, TStatic>::value, "maybe_static_array: TDynamic must be convertible to TStatic"); - -private: - // Static values member - using static_vals_t = static_array<TStatic, Values...>; - constexpr static size_t m_size = sizeof...(Values); - constexpr static size_t m_size_dynamic = - _MDSPAN_FOLD_PLUS_RIGHT((Values == dyn_tag), 0); - - // Dynamic values member - _MDSPAN_NO_UNIQUE_ADDRESS possibly_empty_array<TDynamic, m_size_dynamic> - m_dyn_vals; - - // static mapping of indices to the position in the dynamic values array - using dyn_map_t = index_sequence_scan_impl<0, static_cast<size_t>(Values == dyn_tag)...>; -public: - - // two types for static and dynamic values - using value_type = TDynamic; - using static_value_type = TStatic; - // tag value indicating dynamic value - constexpr static static_value_type tag_value = dyn_tag; - - constexpr maybe_static_array() = default; - - // constructor for all static values - // TODO: add precondition check? - MDSPAN_TEMPLATE_REQUIRES(class... Vals, - /* requires */ ((m_size_dynamic == 0) && - (sizeof...(Vals) > 0))) - MDSPAN_INLINE_FUNCTION - constexpr maybe_static_array(Vals...) : m_dyn_vals{} {} - - // constructors from dynamic values only - MDSPAN_TEMPLATE_REQUIRES(class... DynVals, - /* requires */ (sizeof...(DynVals) == - m_size_dynamic && - m_size_dynamic > 0)) - MDSPAN_INLINE_FUNCTION - constexpr maybe_static_array(DynVals... vals) - : m_dyn_vals{static_cast<TDynamic>(vals)...} {} - - - MDSPAN_TEMPLATE_REQUIRES(class T, size_t N, - /* requires */ (N == m_size_dynamic && N > 0)) - MDSPAN_INLINE_FUNCTION - constexpr maybe_static_array(const std::array<T, N> &vals) { - for (size_t r = 0; r < N; r++) - m_dyn_vals[r] = static_cast<TDynamic>(vals[r]); - } - - MDSPAN_TEMPLATE_REQUIRES(class T, size_t N, - /* requires */ (N == m_size_dynamic && N == 0)) - MDSPAN_INLINE_FUNCTION - constexpr maybe_static_array(const std::array<T, N> &) : m_dyn_vals{} {} - -#ifdef __cpp_lib_span - MDSPAN_TEMPLATE_REQUIRES(class T, size_t N, - /* requires */ (N == m_size_dynamic && N > 0)) - MDSPAN_INLINE_FUNCTION - constexpr maybe_static_array(const std::span<T, N> &vals) { - for (size_t r = 0; r < N; r++) - m_dyn_vals[r] = static_cast<TDynamic>(vals[r]); - } - - MDSPAN_TEMPLATE_REQUIRES(class T, size_t N, - /* requires */ (N == m_size_dynamic && N == 0)) - MDSPAN_INLINE_FUNCTION - constexpr maybe_static_array(const std::span<T, N> &) : m_dyn_vals{} {} -#endif - - // constructors from all values - MDSPAN_TEMPLATE_REQUIRES(class... DynVals, - /* requires */ (sizeof...(DynVals) != - m_size_dynamic && - m_size_dynamic > 0)) - MDSPAN_INLINE_FUNCTION - constexpr maybe_static_array(DynVals... vals) - : m_dyn_vals{} { - static_assert((sizeof...(DynVals) == m_size), "Invalid number of values."); - TDynamic values[m_size]{static_cast<TDynamic>(vals)...}; - for (size_t r = 0; r < m_size; r++) { - TStatic static_val = static_vals_t::get(r); - if (static_val == dyn_tag) { - m_dyn_vals[dyn_map_t::get(r)] = values[r]; - } -// Precondition check -#ifdef _MDSPAN_DEBUG - else { - assert(values[r] == static_cast<TDynamic>(static_val)); - } -#endif - } - } - - MDSPAN_TEMPLATE_REQUIRES( - class T, size_t N, - /* requires */ (N != m_size_dynamic && m_size_dynamic > 0)) - MDSPAN_INLINE_FUNCTION - constexpr maybe_static_array(const std::array<T, N> &vals) { - static_assert((N == m_size), "Invalid number of values."); -// Precondition check -#ifdef _MDSPAN_DEBUG - assert(N == m_size); -#endif - for (size_t r = 0; r < m_size; r++) { - TStatic static_val = static_vals_t::get(r); - if (static_val == dyn_tag) { - m_dyn_vals[dyn_map_t::get(r)] = static_cast<TDynamic>(vals[r]); - } -// Precondition check -#ifdef _MDSPAN_DEBUG - else { - assert(static_cast<TDynamic>(vals[r]) == - static_cast<TDynamic>(static_val)); - } -#endif - } - } - -#ifdef __cpp_lib_span - MDSPAN_TEMPLATE_REQUIRES( - class T, size_t N, - /* requires */ (N != m_size_dynamic && m_size_dynamic > 0)) - MDSPAN_INLINE_FUNCTION - constexpr maybe_static_array(const std::span<T, N> &vals) { - static_assert((N == m_size) || (m_size == dynamic_extent)); -#ifdef _MDSPAN_DEBUG - assert(N == m_size); -#endif - for (size_t r = 0; r < m_size; r++) { - TStatic static_val = static_vals_t::get(r); - if (static_val == dyn_tag) { - m_dyn_vals[dyn_map_t::get(r)] = static_cast<TDynamic>(vals[r]); - } -#ifdef _MDSPAN_DEBUG - else { - assert(static_cast<TDynamic>(vals[r]) == - static_cast<TDynamic>(static_val)); - } -#endif - } - } -#endif - - // access functions - MDSPAN_INLINE_FUNCTION - constexpr static TStatic static_value(size_t r) { return static_vals_t::get(r); } - - MDSPAN_INLINE_FUNCTION - constexpr TDynamic value(size_t r) const { - TStatic static_val = static_vals_t::get(r); - return static_val == dyn_tag ? m_dyn_vals[dyn_map_t::get(r)] - : static_cast<TDynamic>(static_val); - } - MDSPAN_INLINE_FUNCTION - constexpr TDynamic operator[](size_t r) const { return value(r); } - - - // observers - MDSPAN_INLINE_FUNCTION - constexpr static size_t size() { return m_size; } - MDSPAN_INLINE_FUNCTION - constexpr static size_t size_dynamic() { return m_size_dynamic; } -}; - -} // namespace detail -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { - -// ------------------------------------------------------------------ -// ------------ extents --------------------------------------------- -// ------------------------------------------------------------------ - -// Class to describe the extents of a multi dimensional array. -// Used by mdspan, mdarray and layout mappings. -// See ISO C++ standard [mdspan.extents] - -template <class IndexType, size_t... Extents> class extents { -public: - // typedefs for integral types used - using index_type = IndexType; - using size_type = std::make_unsigned_t<index_type>; - using rank_type = size_t; - - static_assert(std::is_integral<index_type>::value && !std::is_same<index_type, bool>::value, - MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents::index_type must be a signed or unsigned integer type"); -private: - constexpr static rank_type m_rank = sizeof...(Extents); - constexpr static rank_type m_rank_dynamic = - _MDSPAN_FOLD_PLUS_RIGHT((Extents == dynamic_extent), /* + ... + */ 0); - - // internal storage type using maybe_static_array - using vals_t = - detail::maybe_static_array<IndexType, size_t, dynamic_extent, Extents...>; - _MDSPAN_NO_UNIQUE_ADDRESS vals_t m_vals; - -public: - // [mdspan.extents.obs], observers of multidimensional index space - MDSPAN_INLINE_FUNCTION - constexpr static rank_type rank() noexcept { return m_rank; } - MDSPAN_INLINE_FUNCTION - constexpr static rank_type rank_dynamic() noexcept { return m_rank_dynamic; } - - MDSPAN_INLINE_FUNCTION - constexpr index_type extent(rank_type r) const noexcept { return m_vals.value(r); } - MDSPAN_INLINE_FUNCTION - constexpr static size_t static_extent(rank_type r) noexcept { - return vals_t::static_value(r); - } - - // [mdspan.extents.cons], constructors - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr extents() noexcept = default; - - // Construction from just dynamic or all values. - // Precondition check is deferred to maybe_static_array constructor - MDSPAN_TEMPLATE_REQUIRES( - class... OtherIndexTypes, - /* requires */ ( - _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(std::is_convertible, OtherIndexTypes, - index_type) /* && ... */) && - _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, - OtherIndexTypes) /* && ... */) && - (sizeof...(OtherIndexTypes) == m_rank || - sizeof...(OtherIndexTypes) == m_rank_dynamic))) - MDSPAN_INLINE_FUNCTION - constexpr explicit extents(OtherIndexTypes... dynvals) noexcept - : m_vals(static_cast<index_type>(dynvals)...) {} - - MDSPAN_TEMPLATE_REQUIRES( - class OtherIndexType, size_t N, - /* requires */ - ( - _MDSPAN_TRAIT(std::is_convertible, const OtherIndexType&, index_type) && - _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, - const OtherIndexType&) && - (N == m_rank || N == m_rank_dynamic))) - MDSPAN_INLINE_FUNCTION - MDSPAN_CONDITIONAL_EXPLICIT(N != m_rank_dynamic) - constexpr extents(const std::array<OtherIndexType, N> &exts) noexcept - : m_vals(std::move(exts)) {} - -#ifdef __cpp_lib_span - MDSPAN_TEMPLATE_REQUIRES( - class OtherIndexType, size_t N, - /* requires */ - (_MDSPAN_TRAIT(std::is_convertible, const OtherIndexType&, index_type) && - _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const OtherIndexType&) && - (N == m_rank || N == m_rank_dynamic))) - MDSPAN_INLINE_FUNCTION - MDSPAN_CONDITIONAL_EXPLICIT(N != m_rank_dynamic) - constexpr extents(const std::span<OtherIndexType, N> &exts) noexcept - : m_vals(std::move(exts)) {} -#endif - -private: - // Function to construct extents storage from other extents. - // With C++ 17 the first two variants could be collapsed using if constexpr - // in which case you don't need all the requires clauses. - // in C++ 14 mode that doesn't work due to infinite recursion - MDSPAN_TEMPLATE_REQUIRES( - size_t DynCount, size_t R, class OtherExtents, class... DynamicValues, - /* requires */ ((R < m_rank) && (static_extent(R) == dynamic_extent))) - MDSPAN_INLINE_FUNCTION - constexpr - vals_t __construct_vals_from_extents(std::integral_constant<size_t, DynCount>, - std::integral_constant<size_t, R>, - const OtherExtents &exts, - DynamicValues... dynamic_values) noexcept { - return __construct_vals_from_extents( - std::integral_constant<size_t, DynCount + 1>(), - std::integral_constant<size_t, R + 1>(), exts, dynamic_values..., - exts.extent(R)); - } - - MDSPAN_TEMPLATE_REQUIRES( - size_t DynCount, size_t R, class OtherExtents, class... DynamicValues, - /* requires */ ((R < m_rank) && (static_extent(R) != dynamic_extent))) - MDSPAN_INLINE_FUNCTION - constexpr - vals_t __construct_vals_from_extents(std::integral_constant<size_t, DynCount>, - std::integral_constant<size_t, R>, - const OtherExtents &exts, - DynamicValues... dynamic_values) noexcept { - return __construct_vals_from_extents( - std::integral_constant<size_t, DynCount>(), - std::integral_constant<size_t, R + 1>(), exts, dynamic_values...); - } - - MDSPAN_TEMPLATE_REQUIRES( - size_t DynCount, size_t R, class OtherExtents, class... DynamicValues, - /* requires */ ((R == m_rank) && (DynCount == m_rank_dynamic))) - MDSPAN_INLINE_FUNCTION - constexpr - vals_t __construct_vals_from_extents(std::integral_constant<size_t, DynCount>, - std::integral_constant<size_t, R>, - const OtherExtents &, - DynamicValues... dynamic_values) noexcept { - return vals_t{static_cast<index_type>(dynamic_values)...}; - } - -public: - - // Converting constructor from other extents specializations - MDSPAN_TEMPLATE_REQUIRES( - class OtherIndexType, size_t... OtherExtents, - /* requires */ - ( - /* multi-stage check to protect from invalid pack expansion when sizes - don't match? */ - decltype(detail::__check_compatible_extents( - // using: sizeof...(Extents) == sizeof...(OtherExtents) as the second argument fails with MSVC+NVCC with some obscure expansion error - // MSVC: 19.38.33133 NVCC: 12.0 - std::integral_constant<bool, extents<int, Extents...>::rank() == extents<int, OtherExtents...>::rank()>{}, - std::integer_sequence<size_t, Extents...>{}, - std::integer_sequence<size_t, OtherExtents...>{}))::value - ) - ) - MDSPAN_INLINE_FUNCTION - MDSPAN_CONDITIONAL_EXPLICIT((((Extents != dynamic_extent) && - (OtherExtents == dynamic_extent)) || - ...) || - (std::numeric_limits<index_type>::max() < - std::numeric_limits<OtherIndexType>::max())) - constexpr extents(const extents<OtherIndexType, OtherExtents...> &other) noexcept - : m_vals(__construct_vals_from_extents( - std::integral_constant<size_t, 0>(), - std::integral_constant<size_t, 0>(), other)) {} - - // Comparison operator - template <class OtherIndexType, size_t... OtherExtents> - MDSPAN_INLINE_FUNCTION friend constexpr bool - operator==(const extents &lhs, - const extents<OtherIndexType, OtherExtents...> &rhs) noexcept { - return - rank() == extents<OtherIndexType, OtherExtents...>::rank() && - detail::rankwise_equal(detail::with_rank<rank()>{}, rhs, lhs, detail::extent); - } - -#if !(MDSPAN_HAS_CXX_20) - template <class OtherIndexType, size_t... OtherExtents> - MDSPAN_INLINE_FUNCTION friend constexpr bool - operator!=(extents const &lhs, - extents<OtherIndexType, OtherExtents...> const &rhs) noexcept { - return !(lhs == rhs); - } -#endif -}; - -// Recursive helper classes to implement dextents alias for extents -namespace detail { - -template <class IndexType, size_t Rank, - class Extents = ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<IndexType>> -struct __make_dextents; - -template <class IndexType, size_t Rank, size_t... ExtentsPack> -struct __make_dextents< - IndexType, Rank, ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<IndexType, ExtentsPack...>> -{ - using type = typename __make_dextents< - IndexType, Rank - 1, - ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<IndexType, - ::MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent, - ExtentsPack...>>::type; -}; - -template <class IndexType, size_t... ExtentsPack> -struct __make_dextents< - IndexType, 0, ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<IndexType, ExtentsPack...>> -{ - using type = ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<IndexType, ExtentsPack...>; -}; - -} // end namespace detail - -// [mdspan.extents.dextents], alias template -template <class IndexType, size_t Rank> -using dextents = typename detail::__make_dextents<IndexType, Rank>::type; - -// Deduction guide for extents -#if defined(_MDSPAN_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION) -template <class... IndexTypes> -extents(IndexTypes...) - -> extents<size_t, - ((void) sizeof(IndexTypes), ::MDSPAN_IMPL_STANDARD_NAMESPACE::dynamic_extent)...>; -#endif - -// Helper type traits for identifying a class as extents. -namespace detail { - -template <class T> struct __is_extents : ::std::false_type {}; - -template <class IndexType, size_t... ExtentsPack> -struct __is_extents<::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<IndexType, ExtentsPack...>> - : ::std::true_type {}; - -template <class T> -#if MDSPAN_HAS_CXX_17 -inline -#else -static -#endif -constexpr bool __is_extents_v = __is_extents<T>::value; - -template<class InputIndexType, class ExtentsIndexType> -MDSPAN_INLINE_FUNCTION -constexpr void -check_lower_bound(InputIndexType user_index, - ExtentsIndexType /* current_extent */, - std::true_type /* is_signed */) -{ - (void) user_index; // prevent unused variable warning -#ifdef _MDSPAN_DEBUG - assert(static_cast<ExtentsIndexType>(user_index) >= 0); -#endif -} - -template<class InputIndexType, class ExtentsIndexType> -MDSPAN_INLINE_FUNCTION -constexpr void -check_lower_bound(InputIndexType /* user_index */, - ExtentsIndexType /* current_extent */, - std::false_type /* is_signed */) -{} - -template<class InputIndexType, class ExtentsIndexType> -MDSPAN_INLINE_FUNCTION -constexpr void -check_upper_bound(InputIndexType user_index, - ExtentsIndexType current_extent) -{ - (void) user_index; // prevent unused variable warnings - (void) current_extent; -#ifdef _MDSPAN_DEBUG - assert(static_cast<ExtentsIndexType>(user_index) < current_extent); -#endif -} - -// Returning true to use AND fold instead of comma -// CPP14 mode doesn't like the use of void expressions -// with the way the _MDSPAN_FOLD_AND is set up -template<class InputIndex, class ExtentsIndexType> -MDSPAN_INLINE_FUNCTION -constexpr bool -check_one_index(InputIndex user_index, - ExtentsIndexType current_extent) -{ - check_lower_bound(user_index, current_extent, - std::integral_constant<bool, std::is_signed<ExtentsIndexType>::value>{}); - check_upper_bound(user_index, current_extent); - return true; -} - -template<size_t ... RankIndices, - class ExtentsIndexType, size_t ... Exts, - class ... Indices> -MDSPAN_INLINE_FUNCTION -constexpr void -check_all_indices_helper(std::index_sequence<RankIndices...>, - const extents<ExtentsIndexType, Exts...>& exts, - Indices... indices) -{ - // Suppress warning about statement has no effect - (void) _MDSPAN_FOLD_AND( - (check_one_index(indices, exts.extent(RankIndices))) - ); -} - -template<class ExtentsIndexType, size_t ... Exts, - class ... Indices> -MDSPAN_INLINE_FUNCTION -constexpr void -check_all_indices(const extents<ExtentsIndexType, Exts...>& exts, - Indices... indices) -{ - check_all_indices_helper(std::make_index_sequence<sizeof...(Indices)>(), - exts, indices...); -} - -} // namespace detail -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/full_extent_t.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/full_extent_t.hpp deleted file mode 100644 index bd4b5c6a8baa31a21281b1528ae2f57a264a7d53..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/full_extent_t.hpp +++ /dev/null @@ -1,26 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER -#pragma once - -#include "macros.hpp" - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { - -struct full_extent_t { explicit full_extent_t() = default; }; - -_MDSPAN_INLINE_VARIABLE constexpr auto full_extent = full_extent_t{ }; - -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/layout_left.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/layout_left.hpp deleted file mode 100644 index 222fba7aa04951df4f73b7894db14b6ab34233c3..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/layout_left.hpp +++ /dev/null @@ -1,266 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER -#pragma once - -#include "macros.hpp" -#include "trait_backports.hpp" -#include "extents.hpp" -#include "layout_stride.hpp" -#include "utility.hpp" -#if MDSPAN_HAS_CXX_17 -#include "../__p2642_bits/layout_padded_fwd.hpp" -#endif -#include <type_traits> - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { - -//============================================================================== - -template <class Extents> -class layout_left::mapping { - public: - using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_left; - private: - - static_assert(detail::__is_extents_v<extents_type>, - MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::layout_left::mapping must be instantiated with a specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents."); - - template <class> - friend class mapping; - - // i0+(i1 + E(1)*(i2 + E(2)*i3)) - template <size_t r, size_t Rank> - struct __rank_count {}; - - template <size_t r, size_t Rank, class I, class... Indices> - _MDSPAN_HOST_DEVICE - constexpr index_type __compute_offset( - __rank_count<r,Rank>, const I& i, Indices... idx) const { - return __compute_offset(__rank_count<r+1,Rank>(), idx...) * - __extents.extent(r) + i; - } - - template<class I> - _MDSPAN_HOST_DEVICE - constexpr index_type __compute_offset( - __rank_count<extents_type::rank()-1,extents_type::rank()>, const I& i) const { - return i; - } - - _MDSPAN_HOST_DEVICE - constexpr index_type __compute_offset(__rank_count<0,0>) const { return 0; } - - public: - - //-------------------------------------------------------------------------------- - - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping() noexcept = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(mapping const&) noexcept = default; - - _MDSPAN_HOST_DEVICE - constexpr mapping(extents_type const& __exts) noexcept - :__extents(__exts) - { } - - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ ( - _MDSPAN_TRAIT(std::is_constructible, extents_type, OtherExtents) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible<OtherExtents, extents_type>::value)) // needs two () due to comma - MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 - mapping(mapping<OtherExtents> const& other) noexcept // NOLINT(google-explicit-constructor) - :__extents(other.extents()) - { - /* - * TODO: check precondition - * other.required_span_size() is a representable value of type index_type - */ - } - - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ ( - _MDSPAN_TRAIT(std::is_constructible, extents_type, OtherExtents) && - (extents_type::rank() <= 1) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible<OtherExtents, extents_type>::value)) // needs two () due to comma - MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 - mapping(layout_right::mapping<OtherExtents> const& other) noexcept // NOLINT(google-explicit-constructor) - :__extents(other.extents()) - { - /* - * TODO: check precondition - * other.required_span_size() is a representable value of type index_type - */ - } - -#if MDSPAN_HAS_CXX_17 - /** - * Converting constructor from `layout_left_padded::mapping`. - * - * This overload participates in overload resolution only if _Mapping is a layout_left_padded mapping and - * extents_type is constructible from _Mapping::extents_type. - * - * \note There is currently a difference from p2642r2, where this function is specified as taking - * `layout_left_padded< padding_value >::mapping< Extents>`. However, this makes `padding_value` non-deducible. - */ - MDSPAN_TEMPLATE_REQUIRES( - class _Mapping, - /* requires */ ( - MDSPAN_IMPL_PROPOSED_NAMESPACE::detail::is_layout_left_padded_mapping<_Mapping>::value - && std::is_constructible_v<extents_type, typename _Mapping::extents_type> - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible_v<typename _Mapping::extents_type, extents_type>)) - mapping(const _Mapping& __other) noexcept - : __extents(__other.extents()) - { - MDSPAN_IMPL_PROPOSED_NAMESPACE::detail:: - check_padded_layout_converting_constructor_mandates< - extents_type, _Mapping>(detail::with_rank<extents_type::rank()>{}); - MDSPAN_IMPL_PROPOSED_NAMESPACE::detail:: - check_padded_layout_converting_constructor_preconditions< - extents_type>(detail::with_rank<extents_type::rank()>{}, __other); - } -#endif - - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ ( - _MDSPAN_TRAIT(std::is_constructible, extents_type, OtherExtents) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 0)) - MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 - mapping(layout_stride::mapping<OtherExtents> const& other) noexcept // NOLINT(google-explicit-constructor) - :__extents(other.extents()) - { - /* - * TODO: check precondition - * other.required_span_size() is a representable value of type index_type - */ - detail::validate_strides(detail::with_rank<extents_type::rank()>{}, layout_left{}, __extents, other); - } - - MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED mapping& operator=(mapping const&) noexcept = default; - - MDSPAN_INLINE_FUNCTION - constexpr const extents_type& extents() const noexcept { - return __extents; - } - - MDSPAN_INLINE_FUNCTION - constexpr index_type required_span_size() const noexcept { - index_type value = 1; - for(rank_type r=0; r<extents_type::rank(); r++) value*=__extents.extent(r); - return value; - } - - //-------------------------------------------------------------------------------- - - MDSPAN_TEMPLATE_REQUIRES( - class... Indices, - /* requires */ ( - (sizeof...(Indices) == extents_type::rank()) && - (detail::are_valid_indices<index_type, Indices...>()) - ) - ) - _MDSPAN_HOST_DEVICE - constexpr index_type operator()(Indices... idxs) const noexcept { -#if ! defined(NDEBUG) - detail::check_all_indices(this->extents(), idxs...); -#endif // ! NDEBUG - return __compute_offset(__rank_count<0, extents_type::rank()>(), static_cast<index_type>(idxs)...); - } - - - - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { return true; } - - MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_exhaustive() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { return true; } - - MDSPAN_INLINE_FUNCTION - constexpr index_type stride(rank_type i) const noexcept -#if MDSPAN_HAS_CXX_20 - requires ( Extents::rank() > 0 ) -#endif - { - index_type value = 1; - for(rank_type r=0; r<i; r++) value*=__extents.extent(r); - return value; - } - - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ ( Extents::rank() == OtherExtents::rank()) - ) - MDSPAN_INLINE_FUNCTION - friend constexpr bool operator==(mapping const& lhs, mapping<OtherExtents> const& rhs) noexcept { - return lhs.extents() == rhs.extents(); - } - - // In C++ 20 the not equal exists if equal is found -#if !(MDSPAN_HAS_CXX_20) - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ ( Extents::rank() == OtherExtents::rank()) - ) - MDSPAN_INLINE_FUNCTION - friend constexpr bool operator!=(mapping const& lhs, mapping<OtherExtents> const& rhs) noexcept { - return lhs.extents() != rhs.extents(); - } -#endif - - // Not really public, but currently needed to implement fully constexpr useable submdspan: - template<size_t N, class SizeType, size_t ... E, size_t ... Idx> - constexpr index_type __get_stride(MDSPAN_IMPL_STANDARD_NAMESPACE::extents<SizeType, E...>,std::integer_sequence<size_t, Idx...>) const { - return _MDSPAN_FOLD_TIMES_RIGHT((Idx<N? __extents.template __extent<Idx>():1),1); - } - template<size_t N> - constexpr index_type __stride() const noexcept { - return __get_stride<N>(__extents, std::make_index_sequence<extents_type::rank()>()); - } - -private: - _MDSPAN_NO_UNIQUE_ADDRESS extents_type __extents{}; - - // [mdspan.submdspan.mapping], submdspan mapping specialization - template<class... SliceSpecifiers> - MDSPAN_INLINE_FUNCTION - constexpr auto submdspan_mapping_impl( - SliceSpecifiers... slices) const; - - template<class... SliceSpecifiers> - friend constexpr auto submdspan_mapping( - const mapping& src, SliceSpecifiers... slices) { - return src.submdspan_mapping_impl(slices...); - } -}; - - -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE - diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/layout_right.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/layout_right.hpp deleted file mode 100644 index 284569f6533251667d07a8b98de2feb01bbd9381..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/layout_right.hpp +++ /dev/null @@ -1,262 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER -#pragma once - -#include "macros.hpp" -#include "trait_backports.hpp" -#include "extents.hpp" -#include "layout_stride.hpp" -#include "utility.hpp" -#if MDSPAN_HAS_CXX_17 -#include "../__p2642_bits/layout_padded_fwd.hpp" -#endif - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { - -//============================================================================== -template <class Extents> -class layout_right::mapping { - public: - using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_right; - private: - - static_assert(detail::__is_extents_v<extents_type>, - MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::layout_right::mapping must be instantiated with a specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents."); - - template <class> - friend class mapping; - - // i0+(i1 + E(1)*(i2 + E(2)*i3)) - template <size_t r, size_t Rank> - struct __rank_count {}; - - template <size_t r, size_t Rank, class I, class... Indices> - _MDSPAN_HOST_DEVICE - constexpr index_type __compute_offset( - index_type offset, __rank_count<r,Rank>, const I& i, Indices... idx) const { - return __compute_offset(offset * __extents.extent(r) + i,__rank_count<r+1,Rank>(), idx...); - } - - template<class I, class ... Indices> - _MDSPAN_HOST_DEVICE - constexpr index_type __compute_offset( - __rank_count<0,extents_type::rank()>, const I& i, Indices... idx) const { - return __compute_offset(i,__rank_count<1,extents_type::rank()>(),idx...); - } - - _MDSPAN_HOST_DEVICE - constexpr index_type __compute_offset(size_t offset, __rank_count<extents_type::rank(), extents_type::rank()>) const { - return static_cast<index_type>(offset); - } - - _MDSPAN_HOST_DEVICE - constexpr index_type __compute_offset(__rank_count<0,0>) const { return 0; } - - public: - - //-------------------------------------------------------------------------------- - - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping() noexcept = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(mapping const&) noexcept = default; - - _MDSPAN_HOST_DEVICE - constexpr mapping(extents_type const& __exts) noexcept - :__extents(__exts) - { } - - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ ( - _MDSPAN_TRAIT(std::is_constructible, extents_type, OtherExtents) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible<OtherExtents, extents_type>::value)) // needs two () due to comma - MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 - mapping(mapping<OtherExtents> const& other) noexcept // NOLINT(google-explicit-constructor) - :__extents(other.extents()) - { - /* - * TODO: check precondition - * other.required_span_size() is a representable value of type index_type - */ - } - - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ ( - _MDSPAN_TRAIT(std::is_constructible, extents_type, OtherExtents) && - (extents_type::rank() <= 1) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible<OtherExtents, extents_type>::value)) // needs two () due to comma - MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 - mapping(layout_left::mapping<OtherExtents> const& other) noexcept // NOLINT(google-explicit-constructor) - :__extents(other.extents()) - { - /* - * TODO: check precondition - * other.required_span_size() is a representable value of type index_type - */ - } - - /** - * Converting constructor from `layout_right_padded::mapping`. - * - * This overload participates in overload resolution only if _Mapping is a layout_right_padded mapping and - * extents_type is constructible from _Mapping::extents_type. - * - * \note There is currently a difference from p2642r2, where this function is specified as taking - * `layout_right_padded< padding_value >::mapping< Extents>`. However, this makes `padding_value` non-deducible. - */ -#if MDSPAN_HAS_CXX_17 - MDSPAN_TEMPLATE_REQUIRES( - class _Mapping, - /* requires */ ( - MDSPAN_IMPL_PROPOSED_NAMESPACE::detail::is_layout_right_padded_mapping<_Mapping>::value - && std::is_constructible_v<extents_type, typename _Mapping::extents_type>)) - MDSPAN_CONDITIONAL_EXPLICIT((!std::is_convertible_v<typename _Mapping::extents_type, extents_type>)) - mapping(const _Mapping &__other) noexcept - : __extents(__other.extents()) - { - MDSPAN_IMPL_PROPOSED_NAMESPACE::detail:: - check_padded_layout_converting_constructor_mandates< - extents_type, _Mapping>(detail::with_rank<extents_type::rank()>{}); - MDSPAN_IMPL_PROPOSED_NAMESPACE::detail:: - check_padded_layout_converting_constructor_preconditions< - extents_type>(detail::with_rank<extents_type::rank()>{}, __other); - } -#endif - - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ ( - _MDSPAN_TRAIT(std::is_constructible, extents_type, OtherExtents) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 0)) - MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 - mapping(layout_stride::mapping<OtherExtents> const& other) noexcept // NOLINT(google-explicit-constructor) - :__extents(other.extents()) - { - /* - * TODO: check precondition - * other.required_span_size() is a representable value of type index_type - */ - detail::validate_strides(detail::with_rank<extents_type::rank()>{}, layout_right{}, __extents, other); - } - - MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED mapping& operator=(mapping const&) noexcept = default; - - MDSPAN_INLINE_FUNCTION - constexpr const extents_type& extents() const noexcept { - return __extents; - } - - MDSPAN_INLINE_FUNCTION - constexpr index_type required_span_size() const noexcept { - index_type value = 1; - for(rank_type r=0; r != extents_type::rank(); ++r) value*=__extents.extent(r); - return value; - } - - //-------------------------------------------------------------------------------- - - MDSPAN_TEMPLATE_REQUIRES( - class ... Indices, - /* requires */ ( - (sizeof...(Indices) == extents_type::rank()) && - (detail::are_valid_indices<index_type, Indices...>()) - ) - ) - _MDSPAN_HOST_DEVICE - constexpr index_type operator()(Indices... idxs) const noexcept { -#if ! defined(NDEBUG) - detail::check_all_indices(this->extents(), idxs...); -#endif // ! NDEBUG - return __compute_offset(__rank_count<0, extents_type::rank()>(), static_cast<index_type>(idxs)...); - } - - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_exhaustive() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { return true; } - - MDSPAN_INLINE_FUNCTION - constexpr index_type stride(rank_type i) const noexcept -#if MDSPAN_HAS_CXX_20 - requires ( Extents::rank() > 0 ) -#endif - { - index_type value = 1; - for(rank_type r=extents_type::rank()-1; r>i; r--) value*=__extents.extent(r); - return value; - } - - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ ( Extents::rank() == OtherExtents::rank()) - ) - MDSPAN_INLINE_FUNCTION - friend constexpr bool operator==(mapping const& lhs, mapping<OtherExtents> const& rhs) noexcept { - return lhs.extents() == rhs.extents(); - } - - // In C++ 20 the not equal exists if equal is found -#if !(MDSPAN_HAS_CXX_20) - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ (Extents::rank() == OtherExtents::rank()) - ) - MDSPAN_INLINE_FUNCTION - friend constexpr bool operator!=(mapping const& lhs, mapping<OtherExtents> const& rhs) noexcept { - return lhs.extents() != rhs.extents(); - } -#endif - - // Not really public, but currently needed to implement fully constexpr useable submdspan: - template<size_t N, class SizeType, size_t ... E, size_t ... Idx> - constexpr index_type __get_stride(MDSPAN_IMPL_STANDARD_NAMESPACE::extents<SizeType, E...>,std::integer_sequence<size_t, Idx...>) const { - return _MDSPAN_FOLD_TIMES_RIGHT((Idx>N? __extents.template __extent<Idx>():1),1); - } - template<size_t N> - constexpr index_type __stride() const noexcept { - return __get_stride<N>(__extents, std::make_index_sequence<extents_type::rank()>()); - } - -private: - _MDSPAN_NO_UNIQUE_ADDRESS extents_type __extents{}; - - // [mdspan.submdspan.mapping], submdspan mapping specialization - template<class... SliceSpecifiers> - MDSPAN_INLINE_FUNCTION - constexpr auto submdspan_mapping_impl( - SliceSpecifiers... slices) const; - - template<class... SliceSpecifiers> - friend constexpr auto submdspan_mapping( - const mapping& src, SliceSpecifiers... slices) { - return src.submdspan_mapping_impl(slices...); - } -}; - -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE - diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/layout_stride.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/layout_stride.hpp deleted file mode 100644 index ea2cd3802fd942d30dd8293217cc5c0dc498b8b1..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/layout_stride.hpp +++ /dev/null @@ -1,667 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER -#pragma once - -#include "macros.hpp" -#include "extents.hpp" -#include "trait_backports.hpp" -#include "compressed_pair.hpp" -#include "utility.hpp" - -#if !defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) -# include "no_unique_address.hpp" -#endif - -#include <array> -#include <type_traits> -#include <utility> - -#ifdef __cpp_lib_span -#include <span> -#endif -#if defined(_MDSPAN_USE_CONCEPTS) && MDSPAN_HAS_CXX_20 && defined(__cpp_lib_concepts) -# include <concepts> -#endif - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { - -struct layout_left { - template<class Extents> - class mapping; -}; -struct layout_right { - template<class Extents> - class mapping; -}; - -namespace detail { - template<class Layout, class Mapping> - constexpr bool __is_mapping_of = - std::is_same<typename Layout::template mapping<typename Mapping::extents_type>, Mapping>::value; - -#if defined(_MDSPAN_USE_CONCEPTS) && MDSPAN_HAS_CXX_20 -# if !defined(__cpp_lib_concepts) - namespace internal { - namespace detail { - template <typename _Tp, typename _Up> - concept __same_as = std::is_same_v<_Tp, _Up>; - } // namespace detail - template <class T, class U> - concept __same_as = detail::__same_as<T, U> && detail::__same_as<U, T>; - } // namespace internal -# endif - - template<class M> - concept __layout_mapping_alike = requires { - requires __is_extents<typename M::extents_type>::value; -#if defined(__cpp_lib_concepts) - { M::is_always_strided() } -> std::same_as<bool>; - { M::is_always_exhaustive() } -> std::same_as<bool>; - { M::is_always_unique() } -> std::same_as<bool>; -#else - { M::is_always_strided() } -> internal::__same_as<bool>; - { M::is_always_exhaustive() } -> internal::__same_as<bool>; - { M::is_always_unique() } -> internal::__same_as<bool>; -#endif - std::bool_constant<M::is_always_strided()>::value; - std::bool_constant<M::is_always_exhaustive()>::value; - std::bool_constant<M::is_always_unique()>::value; - }; -#endif - -} // namespace detail - -struct layout_stride { - template <class Extents> - class mapping -#if !defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - : private detail::__no_unique_address_emulation< - detail::__compressed_pair< - Extents, - detail::possibly_empty_array<typename Extents::index_type, Extents::rank()> - > - > -#endif - { - public: - using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_stride; - - // This could be a `requires`, but I think it's better and clearer as a `static_assert`. - static_assert(detail::__is_extents_v<Extents>, - MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::layout_stride::mapping must be instantiated with a specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents."); - - - private: - - //---------------------------------------------------------------------------- - - using __strides_storage_t = detail::possibly_empty_array<index_type, extents_type::rank()>; - using __member_pair_t = detail::__compressed_pair<extents_type, __strides_storage_t>; - -#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - _MDSPAN_NO_UNIQUE_ADDRESS __member_pair_t __members; -#else - using __base_t = detail::__no_unique_address_emulation<__member_pair_t>; -#endif - - MDSPAN_FORCE_INLINE_FUNCTION constexpr __strides_storage_t const& - __strides_storage() const noexcept { -#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - return __members.__second(); -#else - return this->__base_t::__ref().__second(); -#endif - } - MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 __strides_storage_t& - __strides_storage() noexcept { -#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - return __members.__second(); -#else - return this->__base_t::__ref().__second(); -#endif - } - - template<class SizeType, size_t ... Ep, size_t ... Idx> - _MDSPAN_HOST_DEVICE - constexpr index_type __get_size(::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<SizeType, Ep...>,std::integer_sequence<size_t, Idx...>) const { - return _MDSPAN_FOLD_TIMES_RIGHT( static_cast<index_type>(extents().extent(Idx)), 1 ); - } - - //---------------------------------------------------------------------------- - - template <class> - friend class mapping; - - //---------------------------------------------------------------------------- - - // Workaround for non-deducibility of the index sequence template parameter if it's given at the top level - template <class> - struct __deduction_workaround; - - template <size_t... Idxs> - struct __deduction_workaround<std::index_sequence<Idxs...>> - { - template <class OtherExtents> - MDSPAN_INLINE_FUNCTION - static constexpr bool _eq_impl(mapping const& self, mapping<OtherExtents> const& other) noexcept { - using common_t = std::common_type_t<index_type, typename OtherExtents::index_type>; - return _MDSPAN_FOLD_AND((static_cast<common_t>(self.stride(Idxs)) == static_cast<common_t>(other.stride(Idxs))) /* && ... */) - && _MDSPAN_FOLD_AND((static_cast<common_t>(self.extents().extent(Idxs)) == static_cast<common_t>(other.extents().extent(Idxs))) /* || ... */); - } - template <class OtherExtents> - MDSPAN_INLINE_FUNCTION - static constexpr bool _not_eq_impl(mapping const& self, mapping<OtherExtents> const& other) noexcept { - using common_t = std::common_type_t<index_type, typename OtherExtents::index_type>; - return _MDSPAN_FOLD_OR((static_cast<common_t>(self.stride(Idxs)) != static_cast<common_t>(other.stride(Idxs))) /* || ... */) - || _MDSPAN_FOLD_OR((static_cast<common_t>(self.extents().extent(Idxs)) != static_cast<common_t>(other.extents().extent(Idxs))) /* || ... */); - } - - template <class... Integral> - MDSPAN_FORCE_INLINE_FUNCTION - static constexpr size_t _call_op_impl(mapping const& self, Integral... idxs) noexcept { - return _MDSPAN_FOLD_PLUS_RIGHT((idxs * self.stride(Idxs)), /* + ... + */ 0); - } - - MDSPAN_INLINE_FUNCTION - static constexpr size_t _req_span_size_impl(mapping const& self) noexcept { - // assumes no negative strides; not sure if I'm allowed to assume that or not - return __impl::_call_op_impl(self, (self.extents().template __extent<Idxs>() - 1)...) + 1; - } - - template<class OtherMapping> - MDSPAN_INLINE_FUNCTION - static constexpr const __strides_storage_t fill_strides(const OtherMapping& map) { - return __strides_storage_t{static_cast<index_type>(map.stride(Idxs))...}; - } - - MDSPAN_INLINE_FUNCTION - static constexpr const __strides_storage_t& fill_strides(const __strides_storage_t& s) { - return s; - } - - template<class IntegralType> - MDSPAN_INLINE_FUNCTION - static constexpr const __strides_storage_t fill_strides(const std::array<IntegralType,extents_type::rank()>& s) { - return __strides_storage_t{static_cast<index_type>(s[Idxs])...}; - } - - MDSPAN_TEMPLATE_REQUIRES( - class IntegralType, - // The is_convertible condition is added to make sfinae valid - // the extents_type::rank() > 0 is added to avoid use of non-standard zero length c-array - (std::is_convertible<IntegralType, typename extents_type::index_type>::value && (extents_type::rank() > 0)) - ) - MDSPAN_INLINE_FUNCTION - // despite the requirement some compilers still complain about zero length array during parsing - // making it length 1 now, but since the thing can't be instantiated due to requirement the actual - // instantiation of strides_storage will not fail despite mismatching length - static constexpr const __strides_storage_t fill_strides(mdspan_non_standard_tag, const IntegralType (&s)[extents_type::rank()>0?extents_type::rank():1]) { - return __strides_storage_t{static_cast<index_type>(s[Idxs])...}; - } - -#ifdef __cpp_lib_span - template<class IntegralType> - MDSPAN_INLINE_FUNCTION - static constexpr const __strides_storage_t fill_strides(const std::span<IntegralType,extents_type::rank()>& s) { - return __strides_storage_t{static_cast<index_type>(s[Idxs])...}; - } -#endif - - MDSPAN_INLINE_FUNCTION - static constexpr std::array<index_type, extents_type::rank()> return_strides(const __strides_storage_t& s) { - return std::array<index_type, extents_type::rank()>{s[Idxs]...}; - } - - template<size_t K> - MDSPAN_INLINE_FUNCTION - static constexpr size_t __return_zero() { return 0; } - - template<class Mapping> - MDSPAN_INLINE_FUNCTION - static constexpr typename Mapping::index_type - __OFFSET(const Mapping& m) { return m(__return_zero<Idxs>()...); } - }; - - // Can't use defaulted parameter in the __deduction_workaround template because of a bug in MSVC warning C4348. - using __impl = __deduction_workaround<std::make_index_sequence<Extents::rank()>>; - - static constexpr __strides_storage_t strides_storage(detail::with_rank<0>) { - return {}; - } - template <std::size_t N> - static constexpr __strides_storage_t strides_storage(detail::with_rank<N>) { - __strides_storage_t s{}; - - extents_type e; - index_type stride = 1; - for(int r = static_cast<int>(extents_type::rank() - 1); r >= 0; r--) { - s[r] = stride; - stride *= e.extent(r); - } - - return s; - } - - //---------------------------------------------------------------------------- - -#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - MDSPAN_INLINE_FUNCTION constexpr explicit - mapping(__member_pair_t&& __m) : __members(::std::move(__m)) {} -#else - MDSPAN_INLINE_FUNCTION constexpr explicit - mapping(__base_t&& __b) : __base_t(::std::move(__b)) {} -#endif - - public: - - //-------------------------------------------------------------------------------- - - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping() noexcept -#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - : __members{ -#else - : __base_t(__base_t{__member_pair_t( -#endif - extents_type(), - __strides_storage_t(strides_storage(detail::with_rank<extents_type::rank()>{})) -#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - } -#else - )}) -#endif - {} - - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(mapping const&) noexcept = default; - - MDSPAN_TEMPLATE_REQUIRES( - class IntegralTypes, - /* requires */ ( - // MSVC 19.32 does not like using index_type here, requires the typename Extents::index_type - // error C2641: cannot deduce template arguments for 'MDSPAN_IMPL_STANDARD_NAMESPACE::layout_stride::mapping' - _MDSPAN_TRAIT(std::is_convertible, const std::remove_const_t<IntegralTypes>&, typename Extents::index_type) && - _MDSPAN_TRAIT(std::is_nothrow_constructible, typename Extents::index_type, const std::remove_const_t<IntegralTypes>&) - ) - ) - MDSPAN_INLINE_FUNCTION - constexpr - mapping( - extents_type const& e, - std::array<IntegralTypes, extents_type::rank()> const& s - ) noexcept -#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - : __members{ -#else - : __base_t(__base_t{__member_pair_t( -#endif - e, __strides_storage_t(__impl::fill_strides(s)) -#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - } -#else - )}) -#endif - { - /* - * TODO: check preconditions - * - s[i] > 0 is true for all i in the range [0, rank_ ). - * - REQUIRED-SPAN-SIZE(e, s) is a representable value of type index_type ([basic.fundamental]). - * - If rank_ is greater than 0, then there exists a permutation P of the integers in the - * range [0, rank_), such that s[ pi ] >= s[ pi − 1 ] * e.extent( pi − 1 ) is true for - * all i in the range [1, rank_ ), where pi is the ith element of P. - */ - } - - MDSPAN_TEMPLATE_REQUIRES( - class IntegralTypes, - /* requires */ ( - // MSVC 19.32 does not like using index_type here, requires the typename Extents::index_type - // error C2641: cannot deduce template arguments for 'MDSPAN_IMPL_STANDARD_NAMESPACE::layout_stride::mapping' - _MDSPAN_TRAIT(std::is_convertible, const std::remove_const_t<IntegralTypes>&, typename Extents::index_type) && - _MDSPAN_TRAIT(std::is_nothrow_constructible, typename Extents::index_type, const std::remove_const_t<IntegralTypes>&) && - (Extents::rank() > 0) - ) - ) - MDSPAN_INLINE_FUNCTION - constexpr - mapping( - mdspan_non_standard_tag, - extents_type const& e, - // despite the requirement some compilers still complain about zero length array during parsing - // making it length 1 now, but since the thing can't be instantiated due to requirement the actual - // instantiation of strides_storage will not fail despite mismatching length - IntegralTypes (&s)[extents_type::rank()>0?extents_type::rank():1] - ) noexcept -#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - : __members{ -#else - : __base_t(__base_t{__member_pair_t( -#endif - e, __strides_storage_t(__impl::fill_strides(mdspan_non_standard, s)) -#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - } -#else - )}) -#endif - { - /* - * TODO: check preconditions - * - s[i] > 0 is true for all i in the range [0, rank_ ). - * - REQUIRED-SPAN-SIZE(e, s) is a representable value of type index_type ([basic.fundamental]). - * - If rank_ is greater than 0, then there exists a permutation P of the integers in the - * range [0, rank_), such that s[ pi ] >= s[ pi − 1 ] * e.extent( pi − 1 ) is true for - * all i in the range [1, rank_ ), where pi is the ith element of P. - */ - } - -#ifdef __cpp_lib_span - MDSPAN_TEMPLATE_REQUIRES( - class IntegralTypes, - /* requires */ ( - // MSVC 19.32 does not like using index_type here, requires the typename Extents::index_type - // error C2641: cannot deduce template arguments for 'MDSPAN_IMPL_STANDARD_NAMESPACE::layout_stride::mapping' - _MDSPAN_TRAIT(std::is_convertible, const std::remove_const_t<IntegralTypes>&, typename Extents::index_type) && - _MDSPAN_TRAIT(std::is_nothrow_constructible, typename Extents::index_type, const std::remove_const_t<IntegralTypes>&) - ) - ) - MDSPAN_INLINE_FUNCTION - constexpr - mapping( - extents_type const& e, - std::span<IntegralTypes, extents_type::rank()> const& s - ) noexcept -#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - : __members{ -#else - : __base_t(__base_t{__member_pair_t( -#endif - e, __strides_storage_t(__impl::fill_strides(s)) -#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - } -#else - )}) -#endif - { - /* - * TODO: check preconditions - * - s[i] > 0 is true for all i in the range [0, rank_ ). - * - REQUIRED-SPAN-SIZE(e, s) is a representable value of type index_type ([basic.fundamental]). - * - If rank_ is greater than 0, then there exists a permutation P of the integers in the - * range [0, rank_), such that s[ pi ] >= s[ pi − 1 ] * e.extent( pi − 1 ) is true for - * all i in the range [1, rank_ ), where pi is the ith element of P. - */ - } -#endif // __cpp_lib_span - -#if !(defined(_MDSPAN_USE_CONCEPTS) && MDSPAN_HAS_CXX_20) - MDSPAN_TEMPLATE_REQUIRES( - class StridedLayoutMapping, - /* requires */ ( - _MDSPAN_TRAIT(std::is_constructible, extents_type, typename StridedLayoutMapping::extents_type) && - detail::__is_mapping_of<typename StridedLayoutMapping::layout_type, StridedLayoutMapping> && - StridedLayoutMapping::is_always_unique() && - StridedLayoutMapping::is_always_strided() - ) - ) -#else - template<class StridedLayoutMapping> - requires( - detail::__layout_mapping_alike<StridedLayoutMapping> && - _MDSPAN_TRAIT(std::is_constructible, extents_type, typename StridedLayoutMapping::extents_type) && - StridedLayoutMapping::is_always_unique() && - StridedLayoutMapping::is_always_strided() - ) -#endif - MDSPAN_CONDITIONAL_EXPLICIT( - !(std::is_convertible<typename StridedLayoutMapping::extents_type, extents_type>::value && - (detail::__is_mapping_of<layout_left, StridedLayoutMapping> || - detail::__is_mapping_of<layout_right, StridedLayoutMapping> || - detail::__is_mapping_of<layout_stride, StridedLayoutMapping>)) - ) // needs two () due to comma - MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 - mapping(StridedLayoutMapping const& other) noexcept // NOLINT(google-explicit-constructor) -#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - : __members{ -#else - : __base_t(__base_t{__member_pair_t( -#endif - other.extents(), __strides_storage_t(__impl::fill_strides(other)) -#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - } -#else - )}) -#endif - { - /* - * TODO: check preconditions - * - other.stride(i) > 0 is true for all i in the range [0, rank_ ). - * - other.required_span_size() is a representable value of type index_type ([basic.fundamental]). - * - OFFSET(other) == 0 - */ - } - - //-------------------------------------------------------------------------------- - - MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED - mapping& operator=(mapping const&) noexcept = default; - - MDSPAN_INLINE_FUNCTION constexpr const extents_type& extents() const noexcept { -#if defined(_MDSPAN_USE_ATTRIBUTE_NO_UNIQUE_ADDRESS) - return __members.__first(); -#else - return this->__base_t::__ref().__first(); -#endif - }; - - MDSPAN_INLINE_FUNCTION - constexpr std::array< index_type, extents_type::rank() > strides() const noexcept { - return __impl::return_strides(__strides_storage()); - } - - MDSPAN_INLINE_FUNCTION - constexpr index_type required_span_size() const noexcept { - index_type span_size = 1; - for(unsigned r = 0; r < extents_type::rank(); r++) { - // Return early if any of the extents are zero - if(extents().extent(r)==0) return 0; - span_size += ( static_cast<index_type>(extents().extent(r) - 1 ) * __strides_storage()[r]); - } - return span_size; - } - - - MDSPAN_TEMPLATE_REQUIRES( - class... Indices, - /* requires */ ( - sizeof...(Indices) == Extents::rank() && - (detail::are_valid_indices<index_type, Indices...>()) - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr index_type operator()(Indices... idxs) const noexcept { -#if ! defined(NDEBUG) - detail::check_all_indices(this->extents(), idxs...); -#endif // ! NDEBUG - return static_cast<index_type>(__impl::_call_op_impl(*this, static_cast<index_type>(idxs)...)); - } - - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { return true; } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { - return false; - } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { return true; } - - MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { return true; } - - private: - constexpr bool exhaustive_for_nonzero_span_size() const - { - return required_span_size() == __get_size(extents(), std::make_index_sequence<extents_type::rank()>()); - } - - constexpr bool is_exhaustive_impl(detail::with_rank<0>) const - { - return true; - } - constexpr bool is_exhaustive_impl(detail::with_rank<1>) const - { - if (required_span_size() != static_cast<index_type>(0)) { - return exhaustive_for_nonzero_span_size(); - } - return stride(0) == 1; - } - template <std::size_t N> - constexpr bool is_exhaustive_impl(detail::with_rank<N>) const - { - if (required_span_size() != static_cast<index_type>(0)) { - return exhaustive_for_nonzero_span_size(); - } - - rank_type r_largest = 0; - for (rank_type r = 1; r < extents_type::rank(); r++) { - if (stride(r) > stride(r_largest)) { - r_largest = r; - } - } - for (rank_type r = 0; r < extents_type::rank(); r++) { - if (extents().extent(r) == 0 && r != r_largest) { - return false; - } - } - return true; - } - - public: - MDSPAN_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 bool is_exhaustive() const noexcept { - return is_exhaustive_impl(detail::with_rank<extents_type::rank()>{}); - } - MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { return true; } - - - MDSPAN_INLINE_FUNCTION - constexpr index_type stride(rank_type r) const noexcept { - return __strides_storage()[r]; - } - -#if !(defined(_MDSPAN_USE_CONCEPTS) && MDSPAN_HAS_CXX_20) - MDSPAN_TEMPLATE_REQUIRES( - class StridedLayoutMapping, - /* requires */ ( - detail::__is_mapping_of<typename StridedLayoutMapping::layout_type, StridedLayoutMapping> && - (extents_type::rank() == StridedLayoutMapping::extents_type::rank()) && - StridedLayoutMapping::is_always_strided() - ) - ) -#else - template<class StridedLayoutMapping> - requires( - detail::__layout_mapping_alike<StridedLayoutMapping> && - (extents_type::rank() == StridedLayoutMapping::extents_type::rank()) && - StridedLayoutMapping::is_always_strided() - ) -#endif - MDSPAN_INLINE_FUNCTION - friend constexpr bool operator==(const mapping& x, const StridedLayoutMapping& y) noexcept { - return (x.extents() == y.extents()) && - (__impl::__OFFSET(y) == static_cast<typename StridedLayoutMapping::index_type>(0)) && - detail::rankwise_equal(detail::with_rank<extents_type::rank()>{}, x, y, detail::stride); - } - - // This one is not technically part of the proposal. Just here to make implementation a bit more optimal hopefully - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ ( - (extents_type::rank() == OtherExtents::rank()) - ) - ) - MDSPAN_INLINE_FUNCTION - friend constexpr bool operator==(mapping const& lhs, mapping<OtherExtents> const& rhs) noexcept { - return __impl::_eq_impl(lhs, rhs); - } - -#if !MDSPAN_HAS_CXX_20 - MDSPAN_TEMPLATE_REQUIRES( - class StridedLayoutMapping, - /* requires */ ( - detail::__is_mapping_of<typename StridedLayoutMapping::layout_type, StridedLayoutMapping> && - (extents_type::rank() == StridedLayoutMapping::extents_type::rank()) && - StridedLayoutMapping::is_always_strided() - ) - ) - MDSPAN_INLINE_FUNCTION - friend constexpr bool operator!=(const mapping& x, const StridedLayoutMapping& y) noexcept { - return not (x == y); - } - - MDSPAN_TEMPLATE_REQUIRES( - class OtherExtents, - /* requires */ ( - (extents_type::rank() == OtherExtents::rank()) - ) - ) - MDSPAN_INLINE_FUNCTION - friend constexpr bool operator!=(mapping const& lhs, mapping<OtherExtents> const& rhs) noexcept { - return __impl::_not_eq_impl(lhs, rhs); - } -#endif - - // [mdspan.submdspan.mapping], submdspan mapping specialization - template<class... SliceSpecifiers> - MDSPAN_INLINE_FUNCTION - constexpr auto submdspan_mapping_impl( - SliceSpecifiers... slices) const; - - template<class... SliceSpecifiers> - friend constexpr auto submdspan_mapping( - const mapping& src, SliceSpecifiers... slices) { - return src.submdspan_mapping_impl(slices...); - } - }; -}; - -namespace detail { - -template <class Layout, class Extents, class Mapping> -constexpr void validate_strides(with_rank<0>, Layout, const Extents&, const Mapping&) -{} - -template <std::size_t N, class Layout, class Extents, class Mapping> -constexpr void validate_strides(with_rank<N>, Layout, const Extents& ext, const Mapping& other) -{ - static_assert(std::is_same<typename Mapping::layout_type, layout_stride>::value and - (std::is_same<Layout, layout_left>::value or - std::is_same<Layout, layout_right>::value) - , "This function is only intended to validate construction of " - "a layout_left or layout_right mapping from a layout_stride mapping."); - - constexpr auto is_left = std::is_same<Layout, layout_left>::value; - - typename Extents::index_type expected_stride = 1; - - for (std::size_t r = 0; r < N; r++) { - const std::size_t s = is_left ? r : N - 1 - r; - - MDSPAN_IMPL_PRECONDITION(common_integral_compare(expected_stride, other.stride(s)) - and "invalid strides for layout_{left,right}"); - - expected_stride *= ext.extent(s); - } -} - -} // namespace detail -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/macros.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/macros.hpp deleted file mode 100644 index 30209a6648b6ef8cc4d32d7bb49411275bc24a8f..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/macros.hpp +++ /dev/null @@ -1,699 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER - -#pragma once - -#include "config.hpp" - -#include <cstdio> -#include <cstdlib> -#include <type_traits> // std::is_void -#if defined(_MDSPAN_HAS_CUDA) || defined(_MDSPAN_HAS_HIP) || defined(_MDSPAN_HAS_SYCL) -#include "assert.h" -#endif - -#ifndef _MDSPAN_HOST_DEVICE -# if defined(_MDSPAN_HAS_CUDA) || defined(_MDSPAN_HAS_HIP) -# define _MDSPAN_HOST_DEVICE __host__ __device__ -# else -# define _MDSPAN_HOST_DEVICE -# endif -#endif - -#ifndef MDSPAN_FORCE_INLINE_FUNCTION -# ifdef _MDSPAN_COMPILER_MSVC // Microsoft compilers -# define MDSPAN_FORCE_INLINE_FUNCTION __forceinline _MDSPAN_HOST_DEVICE -# else -# define MDSPAN_FORCE_INLINE_FUNCTION __attribute__((always_inline)) _MDSPAN_HOST_DEVICE -# endif -#endif - -#ifndef MDSPAN_INLINE_FUNCTION -# define MDSPAN_INLINE_FUNCTION inline _MDSPAN_HOST_DEVICE -#endif - -#ifndef MDSPAN_FUNCTION -# define MDSPAN_FUNCTION _MDSPAN_HOST_DEVICE -#endif - -#ifdef _MDSPAN_HAS_HIP -# define MDSPAN_DEDUCTION_GUIDE _MDSPAN_HOST_DEVICE -#else -# define MDSPAN_DEDUCTION_GUIDE -#endif - -// In CUDA defaulted functions do not need host device markup -#ifndef MDSPAN_INLINE_FUNCTION_DEFAULTED -# define MDSPAN_INLINE_FUNCTION_DEFAULTED -#endif - -//============================================================================== -// <editor-fold desc="Preprocessor helpers"> {{{1 - -#define MDSPAN_PP_COUNT(...) \ - _MDSPAN_PP_INTERNAL_EXPAND_ARGS_PRIVATE( \ - _MDSPAN_PP_INTERNAL_ARGS_AUGMENTER(__VA_ARGS__) \ - ) - -#define _MDSPAN_PP_INTERNAL_ARGS_AUGMENTER(...) unused, __VA_ARGS__ -#define _MDSPAN_PP_INTERNAL_EXPAND(x) x -#define _MDSPAN_PP_INTERNAL_EXPAND_ARGS_PRIVATE(...) \ - _MDSPAN_PP_INTERNAL_EXPAND( \ - _MDSPAN_PP_INTERNAL_COUNT_PRIVATE( \ - __VA_ARGS__, 69, 68, 67, 66, 65, 64, 63, 62, 61, \ - 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, \ - 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, \ - 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, \ - 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \ - 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 \ - ) \ - ) -# define _MDSPAN_PP_INTERNAL_COUNT_PRIVATE( \ - _1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, \ - _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \ - _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, \ - _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, \ - _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \ - _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, \ - _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, \ - _70, count, ...) count \ - /**/ - -#define MDSPAN_PP_STRINGIFY_IMPL(x) #x -#define MDSPAN_PP_STRINGIFY(x) MDSPAN_PP_STRINGIFY_IMPL(x) - -#define MDSPAN_PP_CAT_IMPL(x, y) x ## y -#define MDSPAN_PP_CAT(x, y) MDSPAN_PP_CAT_IMPL(x, y) - -#define MDSPAN_PP_EVAL(X, ...) X(__VA_ARGS__) - -#define MDSPAN_PP_REMOVE_PARENS_IMPL(...) __VA_ARGS__ -#define MDSPAN_PP_REMOVE_PARENS(...) MDSPAN_PP_REMOVE_PARENS_IMPL __VA_ARGS__ - -#define MDSPAN_IMPL_STANDARD_NAMESPACE_STRING MDSPAN_PP_STRINGIFY(MDSPAN_IMPL_STANDARD_NAMESPACE) -#define MDSPAN_IMPL_PROPOSED_NAMESPACE_STRING MDSPAN_PP_STRINGIFY(MDSPAN_IMPL_STANDARD_NAMESPACE) "::" MDSPAN_PP_STRINGIFY(MDSPAN_IMPL_PROPOSED_NAMESPACE) - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -namespace detail { - -#if defined(_MDSPAN_HAS_CUDA) || defined(_MDSPAN_HAS_HIP) -MDSPAN_FUNCTION inline void default_precondition_violation_handler(const char* cond, const char* file, unsigned line) -{ - printf("%s:%u: precondition failure: `%s`\n", file, line, cond); - assert(0); -} -#elif defined(_MDSPAN_HAS_SYCL) -MDSPAN_FUNCTION inline void default_precondition_violation_handler(const char* cond, const char* file, unsigned line) -{ - sycl::ext::oneapi::experimental::printf("%s:%u: precondition failure: `%s`\n", file, line, cond); - assert(0); -} -#else -MDSPAN_FUNCTION inline void default_precondition_violation_handler(const char* cond, const char* file, unsigned line) -{ - std::fprintf(stderr, "%s:%u: precondition failure: `%s`\n", file, line, cond); - std::abort(); -} -#endif - -} // namespace detail -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE - -#ifndef MDSPAN_IMPL_PRECONDITION_VIOLATION_HANDLER -#define MDSPAN_IMPL_PRECONDITION_VIOLATION_HANDLER(cond, file, line) \ - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::default_precondition_violation_handler(cond, file, line) -#endif - -#ifndef MDSPAN_IMPL_CHECK_PRECONDITION - #ifndef NDEBUG - #define MDSPAN_IMPL_CHECK_PRECONDITION 0 - #else - #define MDSPAN_IMPL_CHECK_PRECONDITION 1 - #endif -#endif - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -namespace detail { - -template <bool check = MDSPAN_IMPL_CHECK_PRECONDITION> -MDSPAN_FUNCTION constexpr void precondition(const char* cond, const char* file, unsigned line) -{ - if (not check) { return; } - // in case the macro doesn't use the arguments for custom macros - (void) cond; - (void) file; - (void) line; - MDSPAN_IMPL_PRECONDITION_VIOLATION_HANDLER(cond, file, line); -} - -} // namespace detail -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE - -#define MDSPAN_IMPL_PRECONDITION(...) \ - do { \ - if (not (__VA_ARGS__)) { \ - MDSPAN_IMPL_STANDARD_NAMESPACE::detail::precondition(#__VA_ARGS__, __FILE__, __LINE__); \ - } \ - } while (0) - -// </editor-fold> end Preprocessor helpers }}}1 -//============================================================================== - -//============================================================================== -// <editor-fold desc="Concept emulation"> {{{1 - -// These compatibility macros don't help with partial ordering, but they should do the trick -// for what we need to do with concepts in mdspan -#ifdef _MDSPAN_USE_CONCEPTS -# define MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) > requires REQ -# define MDSPAN_FUNCTION_REQUIRES(PAREN_PREQUALS, FNAME, PAREN_PARAMS, QUALS, REQ) \ - MDSPAN_PP_REMOVE_PARENS(PAREN_PREQUALS) FNAME PAREN_PARAMS QUALS requires REQ \ - /**/ -#else -# define MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) , typename ::std::enable_if<(REQ), int>::type = 0> -# define MDSPAN_FUNCTION_REQUIRES(PAREN_PREQUALS, FNAME, PAREN_PARAMS, QUALS, REQ) \ - MDSPAN_TEMPLATE_REQUIRES( \ - class __function_requires_ignored=void, \ - (std::is_void<__function_requires_ignored>::value && REQ) \ - ) MDSPAN_PP_REMOVE_PARENS(PAREN_PREQUALS) FNAME PAREN_PARAMS QUALS \ - /**/ -#endif - -#if defined(_MDSPAN_COMPILER_MSVC) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL) -# define MDSPAN_TEMPLATE_REQUIRES(...) \ - MDSPAN_PP_CAT( \ - MDSPAN_PP_CAT(MDSPAN_TEMPLATE_REQUIRES_, MDSPAN_PP_COUNT(__VA_ARGS__))\ - (__VA_ARGS__), \ - ) \ - /**/ -#else -# define MDSPAN_TEMPLATE_REQUIRES(...) \ - MDSPAN_PP_EVAL( \ - MDSPAN_PP_CAT(MDSPAN_TEMPLATE_REQUIRES_, MDSPAN_PP_COUNT(__VA_ARGS__)), \ - __VA_ARGS__ \ - ) \ - /**/ -#endif - -#define MDSPAN_TEMPLATE_REQUIRES_2(TP1, REQ) \ - template<TP1 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_3(TP1, TP2, REQ) \ - template<TP1, TP2 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_4(TP1, TP2, TP3, REQ) \ - template<TP1, TP2, TP3 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_5(TP1, TP2, TP3, TP4, REQ) \ - template<TP1, TP2, TP3, TP4 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_6(TP1, TP2, TP3, TP4, TP5, REQ) \ - template<TP1, TP2, TP3, TP4, TP5 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_7(TP1, TP2, TP3, TP4, TP5, TP6, REQ) \ - template<TP1, TP2, TP3, TP4, TP5, TP6 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_8(TP1, TP2, TP3, TP4, TP5, TP6, TP7, REQ) \ - template<TP1, TP2, TP3, TP4, TP5, TP6, TP7 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_9(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, REQ) \ - template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_10(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, REQ) \ - template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_11(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, REQ) \ - template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_12(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, REQ) \ - template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_13(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, REQ) \ - template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_14(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, REQ) \ - template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_15(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, REQ) \ - template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_16(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, REQ) \ - template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_17(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16, REQ) \ - template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_18(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16, TP17, REQ) \ - template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16, TP17 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_19(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16, TP17, TP18, REQ) \ - template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16, TP17, TP18 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ -#define MDSPAN_TEMPLATE_REQUIRES_20(TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16, TP17, TP18, TP19, REQ) \ - template<TP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10, TP11, TP12, TP13, TP14, TP15, TP16, TP17, TP18, TP19 \ - MDSPAN_CLOSE_ANGLE_REQUIRES(REQ) \ - /**/ - -#define MDSPAN_INSTANTIATE_ONLY_IF_USED \ - MDSPAN_TEMPLATE_REQUIRES( \ - class __instantiate_only_if_used_tparam=void, \ - ( _MDSPAN_TRAIT(std::is_void, __instantiate_only_if_used_tparam) ) \ - ) \ - /**/ - -// </editor-fold> end Concept emulation }}}1 -//============================================================================== - -//============================================================================== -// <editor-fold desc="inline variables"> {{{1 - -#ifdef _MDSPAN_USE_INLINE_VARIABLES -# define _MDSPAN_INLINE_VARIABLE inline -#else -# define _MDSPAN_INLINE_VARIABLE -#endif - -// </editor-fold> end inline variables }}}1 -//============================================================================== - -//============================================================================== -// <editor-fold desc="Return type deduction"> {{{1 - -#if _MDSPAN_USE_RETURN_TYPE_DEDUCTION -# define _MDSPAN_DEDUCE_RETURN_TYPE_SINGLE_LINE(SIGNATURE, BODY) \ - auto MDSPAN_PP_REMOVE_PARENS(SIGNATURE) { return MDSPAN_PP_REMOVE_PARENS(BODY); } -# define _MDSPAN_DEDUCE_DECLTYPE_AUTO_RETURN_TYPE_SINGLE_LINE(SIGNATURE, BODY) \ - decltype(auto) MDSPAN_PP_REMOVE_PARENS(SIGNATURE) { return MDSPAN_PP_REMOVE_PARENS(BODY); } -#else -# define _MDSPAN_DEDUCE_RETURN_TYPE_SINGLE_LINE(SIGNATURE, BODY) \ - auto MDSPAN_PP_REMOVE_PARENS(SIGNATURE) \ - -> std::remove_cv_t<std::remove_reference_t<decltype(BODY)>> \ - { return MDSPAN_PP_REMOVE_PARENS(BODY); } -# define _MDSPAN_DEDUCE_DECLTYPE_AUTO_RETURN_TYPE_SINGLE_LINE(SIGNATURE, BODY) \ - auto MDSPAN_PP_REMOVE_PARENS(SIGNATURE) \ - -> decltype(BODY) \ - { return MDSPAN_PP_REMOVE_PARENS(BODY); } - -#endif - -// </editor-fold> end Return type deduction }}}1 -//============================================================================== - -//============================================================================== -// <editor-fold desc="fold expressions"> {{{1 - -struct __mdspan_enable_fold_comma { }; - -#ifdef _MDSPAN_USE_FOLD_EXPRESSIONS -# define _MDSPAN_FOLD_AND(...) ((__VA_ARGS__) && ...) -# define _MDSPAN_FOLD_AND_TEMPLATE(...) ((__VA_ARGS__) && ...) -# define _MDSPAN_FOLD_OR(...) ((__VA_ARGS__) || ...) -# define _MDSPAN_FOLD_ASSIGN_LEFT(INIT, ...) (INIT = ... = (__VA_ARGS__)) -# define _MDSPAN_FOLD_ASSIGN_RIGHT(PACK, ...) (PACK = ... = (__VA_ARGS__)) -# define _MDSPAN_FOLD_TIMES_RIGHT(PACK, ...) (PACK * ... * (__VA_ARGS__)) -# define _MDSPAN_FOLD_PLUS_RIGHT(PACK, ...) (PACK + ... + (__VA_ARGS__)) -# define _MDSPAN_FOLD_COMMA(...) ((__VA_ARGS__), ...) -#else - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { - -namespace __fold_compatibility_impl { - -// We could probably be more clever here, but at the (small) risk of losing some compiler understanding. For the -// few operations we need, it's not worth generalizing over the operation - -#if _MDSPAN_USE_RETURN_TYPE_DEDUCTION - -MDSPAN_FORCE_INLINE_FUNCTION -constexpr decltype(auto) __fold_right_and_impl() { - return true; -} - -template <class Arg, class... Args> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr decltype(auto) __fold_right_and_impl(Arg&& arg, Args&&... args) { - return ((Arg&&)arg) && __fold_compatibility_impl::__fold_right_and_impl((Args&&)args...); -} - -MDSPAN_FORCE_INLINE_FUNCTION -constexpr decltype(auto) __fold_right_or_impl() { - return false; -} - -template <class Arg, class... Args> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto __fold_right_or_impl(Arg&& arg, Args&&... args) { - return ((Arg&&)arg) || __fold_compatibility_impl::__fold_right_or_impl((Args&&)args...); -} - -template <class Arg1> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto __fold_left_assign_impl(Arg1&& arg1) { - return (Arg1&&)arg1; -} - -template <class Arg1, class Arg2, class... Args> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto __fold_left_assign_impl(Arg1&& arg1, Arg2&& arg2, Args&&... args) { - return __fold_compatibility_impl::__fold_left_assign_impl((((Arg1&&)arg1) = ((Arg2&&)arg2)), (Args&&)args...); -} - -template <class Arg1> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto __fold_right_assign_impl(Arg1&& arg1) { - return (Arg1&&)arg1; -} - -template <class Arg1, class Arg2, class... Args> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto __fold_right_assign_impl(Arg1&& arg1, Arg2&& arg2, Args&&... args) { - return ((Arg1&&)arg1) = __fold_compatibility_impl::__fold_right_assign_impl((Arg2&&)arg2, (Args&&)args...); -} - -template <class Arg1> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto __fold_right_plus_impl(Arg1&& arg1) { - return (Arg1&&)arg1; -} - -template <class Arg1, class Arg2, class... Args> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto __fold_right_plus_impl(Arg1&& arg1, Arg2&& arg2, Args&&... args) { - return ((Arg1&&)arg1) + __fold_compatibility_impl::__fold_right_plus_impl((Arg2&&)arg2, (Args&&)args...); -} - -template <class Arg1> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto __fold_right_times_impl(Arg1&& arg1) { - return (Arg1&&)arg1; -} - -template <class Arg1, class Arg2, class... Args> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr auto __fold_right_times_impl(Arg1&& arg1, Arg2&& arg2, Args&&... args) { - return ((Arg1&&)arg1) * __fold_compatibility_impl::__fold_right_times_impl((Arg2&&)arg2, (Args&&)args...); -} - -#else - -//------------------------------------------------------------------------------ -// <editor-fold desc="right and"> {{{2 - -template <class... Args> -struct __fold_right_and_impl_; -template <> -struct __fold_right_and_impl_<> { - using __rv = bool; - MDSPAN_FORCE_INLINE_FUNCTION - static constexpr __rv - __impl() noexcept { - return true; - } -}; -template <class Arg, class... Args> -struct __fold_right_and_impl_<Arg, Args...> { - using __next_t = __fold_right_and_impl_<Args...>; - using __rv = decltype(std::declval<Arg>() && std::declval<typename __next_t::__rv>()); - MDSPAN_FORCE_INLINE_FUNCTION - static constexpr __rv - __impl(Arg&& arg, Args&&... args) noexcept { - return ((Arg&&)arg) && __next_t::__impl((Args&&)args...); - } -}; - -template <class... Args> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr typename __fold_right_and_impl_<Args...>::__rv -__fold_right_and_impl(Args&&... args) { - return __fold_right_and_impl_<Args...>::__impl((Args&&)args...); -} - -// </editor-fold> end right and }}}2 -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// <editor-fold desc="right or"> {{{2 - -template <class... Args> -struct __fold_right_or_impl_; -template <> -struct __fold_right_or_impl_<> { - using __rv = bool; - MDSPAN_FORCE_INLINE_FUNCTION - static constexpr __rv - __impl() noexcept { - return false; - } -}; -template <class Arg, class... Args> -struct __fold_right_or_impl_<Arg, Args...> { - using __next_t = __fold_right_or_impl_<Args...>; - using __rv = decltype(std::declval<Arg>() || std::declval<typename __next_t::__rv>()); - MDSPAN_FORCE_INLINE_FUNCTION - static constexpr __rv - __impl(Arg&& arg, Args&&... args) noexcept { - return ((Arg&&)arg) || __next_t::__impl((Args&&)args...); - } -}; - -template <class... Args> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr typename __fold_right_or_impl_<Args...>::__rv -__fold_right_or_impl(Args&&... args) { - return __fold_right_or_impl_<Args...>::__impl((Args&&)args...); -} - -// </editor-fold> end right or }}}2 -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// <editor-fold desc="right plus"> {{{2 - -template <class... Args> -struct __fold_right_plus_impl_; -template <class Arg> -struct __fold_right_plus_impl_<Arg> { - using __rv = Arg&&; - MDSPAN_FORCE_INLINE_FUNCTION - static constexpr __rv - __impl(Arg&& arg) noexcept { - return (Arg&&)arg; - } -}; -template <class Arg1, class Arg2, class... Args> -struct __fold_right_plus_impl_<Arg1, Arg2, Args...> { - using __next_t = __fold_right_plus_impl_<Arg2, Args...>; - using __rv = decltype(std::declval<Arg1>() + std::declval<typename __next_t::__rv>()); - MDSPAN_FORCE_INLINE_FUNCTION - static constexpr __rv - __impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept { - return ((Arg1&&)arg) + __next_t::__impl((Arg2&&)arg2, (Args&&)args...); - } -}; - -template <class... Args> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr typename __fold_right_plus_impl_<Args...>::__rv -__fold_right_plus_impl(Args&&... args) { - return __fold_right_plus_impl_<Args...>::__impl((Args&&)args...); -} - -// </editor-fold> end right plus }}}2 -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// <editor-fold desc="right times"> {{{2 - -template <class... Args> -struct __fold_right_times_impl_; -template <class Arg> -struct __fold_right_times_impl_<Arg> { - using __rv = Arg&&; - MDSPAN_FORCE_INLINE_FUNCTION - static constexpr __rv - __impl(Arg&& arg) noexcept { - return (Arg&&)arg; - } -}; -template <class Arg1, class Arg2, class... Args> -struct __fold_right_times_impl_<Arg1, Arg2, Args...> { - using __next_t = __fold_right_times_impl_<Arg2, Args...>; - using __rv = decltype(std::declval<Arg1>() * std::declval<typename __next_t::__rv>()); - MDSPAN_FORCE_INLINE_FUNCTION - static constexpr __rv - __impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept { - return ((Arg1&&)arg) * __next_t::__impl((Arg2&&)arg2, (Args&&)args...); - } -}; - -template <class... Args> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr typename __fold_right_times_impl_<Args...>::__rv -__fold_right_times_impl(Args&&... args) { - return __fold_right_times_impl_<Args...>::__impl((Args&&)args...); -} - -// </editor-fold> end right times }}}2 -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// <editor-fold desc="right assign"> {{{2 - -template <class... Args> -struct __fold_right_assign_impl_; -template <class Arg> -struct __fold_right_assign_impl_<Arg> { - using __rv = Arg&&; - MDSPAN_FORCE_INLINE_FUNCTION - static constexpr __rv - __impl(Arg&& arg) noexcept { - return (Arg&&)arg; - } -}; -template <class Arg1, class Arg2, class... Args> -struct __fold_right_assign_impl_<Arg1, Arg2, Args...> { - using __next_t = __fold_right_assign_impl_<Arg2, Args...>; - using __rv = decltype(std::declval<Arg1>() = std::declval<typename __next_t::__rv>()); - MDSPAN_FORCE_INLINE_FUNCTION - static constexpr __rv - __impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept { - return ((Arg1&&)arg) = __next_t::__impl((Arg2&&)arg2, (Args&&)args...); - } -}; - -template <class... Args> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr typename __fold_right_assign_impl_<Args...>::__rv -__fold_right_assign_impl(Args&&... args) { - return __fold_right_assign_impl_<Args...>::__impl((Args&&)args...); -} - -// </editor-fold> end right assign }}}2 -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// <editor-fold desc="left assign"> {{{2 - -template <class... Args> -struct __fold_left_assign_impl_; -template <class Arg> -struct __fold_left_assign_impl_<Arg> { - using __rv = Arg&&; - MDSPAN_FORCE_INLINE_FUNCTION - static constexpr __rv - __impl(Arg&& arg) noexcept { - return (Arg&&)arg; - } -}; -template <class Arg1, class Arg2, class... Args> -struct __fold_left_assign_impl_<Arg1, Arg2, Args...> { - using __assign_result_t = decltype(std::declval<Arg1>() = std::declval<Arg2>()); - using __next_t = __fold_left_assign_impl_<__assign_result_t, Args...>; - using __rv = typename __next_t::__rv; - MDSPAN_FORCE_INLINE_FUNCTION - static constexpr __rv - __impl(Arg1&& arg, Arg2&& arg2, Args&&... args) noexcept { - return __next_t::__impl(((Arg1&&)arg) = (Arg2&&)arg2, (Args&&)args...); - } -}; - -template <class... Args> -MDSPAN_FORCE_INLINE_FUNCTION -constexpr typename __fold_left_assign_impl_<Args...>::__rv -__fold_left_assign_impl(Args&&... args) { - return __fold_left_assign_impl_<Args...>::__impl((Args&&)args...); -} - -// </editor-fold> end left assign }}}2 -//------------------------------------------------------------------------------ - -#endif - - -template <class... Args> -constexpr __mdspan_enable_fold_comma __fold_comma_impl(Args&&... args) noexcept { return { }; } - -template <bool... Bs> -struct __bools; - -} // __fold_compatibility_impl - -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE - -# define _MDSPAN_FOLD_AND(...) MDSPAN_IMPL_STANDARD_NAMESPACE::__fold_compatibility_impl::__fold_right_and_impl((__VA_ARGS__)...) -# define _MDSPAN_FOLD_OR(...) MDSPAN_IMPL_STANDARD_NAMESPACE::__fold_compatibility_impl::__fold_right_or_impl((__VA_ARGS__)...) -# define _MDSPAN_FOLD_ASSIGN_LEFT(INIT, ...) MDSPAN_IMPL_STANDARD_NAMESPACE::__fold_compatibility_impl::__fold_left_assign_impl(INIT, (__VA_ARGS__)...) -# define _MDSPAN_FOLD_ASSIGN_RIGHT(PACK, ...) MDSPAN_IMPL_STANDARD_NAMESPACE::__fold_compatibility_impl::__fold_right_assign_impl((PACK)..., __VA_ARGS__) -# define _MDSPAN_FOLD_TIMES_RIGHT(PACK, ...) MDSPAN_IMPL_STANDARD_NAMESPACE::__fold_compatibility_impl::__fold_right_times_impl((PACK)..., __VA_ARGS__) -# define _MDSPAN_FOLD_PLUS_RIGHT(PACK, ...) MDSPAN_IMPL_STANDARD_NAMESPACE::__fold_compatibility_impl::__fold_right_plus_impl((PACK)..., __VA_ARGS__) -# define _MDSPAN_FOLD_COMMA(...) MDSPAN_IMPL_STANDARD_NAMESPACE::__fold_compatibility_impl::__fold_comma_impl((__VA_ARGS__)...) - -# define _MDSPAN_FOLD_AND_TEMPLATE(...) \ - _MDSPAN_TRAIT(std::is_same, __fold_compatibility_impl::__bools<(__VA_ARGS__)..., true>, __fold_compatibility_impl::__bools<true, (__VA_ARGS__)...>) - -#endif - -// </editor-fold> end fold expressions }}}1 -//============================================================================== - -//============================================================================== -// <editor-fold desc="Variable template compatibility"> {{{1 - -#if _MDSPAN_USE_VARIABLE_TEMPLATES -# define _MDSPAN_TRAIT(TRAIT, ...) TRAIT##_v<__VA_ARGS__> -#else -# define _MDSPAN_TRAIT(TRAIT, ...) TRAIT<__VA_ARGS__>::value -#endif - -// </editor-fold> end Variable template compatibility }}}1 -//============================================================================== - -//============================================================================== -// <editor-fold desc="Pre-C++14 constexpr"> {{{1 - -#if _MDSPAN_USE_CONSTEXPR_14 -# define _MDSPAN_CONSTEXPR_14 constexpr -// Workaround for a bug (I think?) in EDG frontends -# ifdef __EDG__ -# define _MDSPAN_CONSTEXPR_14_DEFAULTED -# else -# define _MDSPAN_CONSTEXPR_14_DEFAULTED constexpr -# endif -#else -# define _MDSPAN_CONSTEXPR_14 -# define _MDSPAN_CONSTEXPR_14_DEFAULTED -#endif - -// </editor-fold> end Pre-C++14 constexpr }}}1 -//============================================================================== diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/mdspan.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/mdspan.hpp deleted file mode 100644 index af4848248d64ced5f5ef0d383561db73a3ee7579..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/mdspan.hpp +++ /dev/null @@ -1,432 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER - -#pragma once - -#include "default_accessor.hpp" -#include "layout_right.hpp" -#include "extents.hpp" -#include "trait_backports.hpp" -#include "compressed_pair.hpp" - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -template < - class ElementType, - class Extents, - class LayoutPolicy = layout_right, - class AccessorPolicy = default_accessor<ElementType> -> -class mdspan -{ -private: - static_assert(detail::__is_extents_v<Extents>, - MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::mdspan's Extents template parameter must be a specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents."); - static_assert(std::is_same<ElementType, typename AccessorPolicy::element_type>::value, - MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::mdspan's ElementType template parameter must be the same as its AccessorPolicy::element_type."); - - // Workaround for non-deducibility of the index sequence template parameter if it's given at the top level - template <class> - struct __deduction_workaround; - - template <size_t... Idxs> - struct __deduction_workaround<std::index_sequence<Idxs...>> - { - MDSPAN_FORCE_INLINE_FUNCTION static constexpr - size_t __size(mdspan const& __self) noexcept { - return _MDSPAN_FOLD_TIMES_RIGHT((__self.__mapping_ref().extents().extent(Idxs)), /* * ... * */ size_t(1)); - } - MDSPAN_FORCE_INLINE_FUNCTION static constexpr - bool __empty(mdspan const& __self) noexcept { - return (__self.rank()>0) && _MDSPAN_FOLD_OR((__self.__mapping_ref().extents().extent(Idxs)==index_type(0))); - } - template <class ReferenceType, class SizeType, size_t N> - MDSPAN_FORCE_INLINE_FUNCTION static constexpr - ReferenceType __callop(mdspan const& __self, const std::array<SizeType, N>& indices) noexcept { - return __self.__accessor_ref().access(__self.__ptr_ref(), __self.__mapping_ref()(indices[Idxs]...)); - } -#ifdef __cpp_lib_span - template <class ReferenceType, class SizeType, size_t N> - MDSPAN_FORCE_INLINE_FUNCTION static constexpr - ReferenceType __callop(mdspan const& __self, const std::span<SizeType, N>& indices) noexcept { - return __self.__accessor_ref().access(__self.__ptr_ref(), __self.__mapping_ref()(indices[Idxs]...)); - } -#endif - }; - -public: - - //-------------------------------------------------------------------------------- - // Domain and codomain types - - using extents_type = Extents; - using layout_type = LayoutPolicy; - using accessor_type = AccessorPolicy; - using mapping_type = typename layout_type::template mapping<extents_type>; - using element_type = ElementType; - using value_type = std::remove_cv_t<element_type>; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using data_handle_type = typename accessor_type::data_handle_type; - using reference = typename accessor_type::reference; - - MDSPAN_INLINE_FUNCTION static constexpr size_t rank() noexcept { return extents_type::rank(); } - MDSPAN_INLINE_FUNCTION static constexpr size_t rank_dynamic() noexcept { return extents_type::rank_dynamic(); } - MDSPAN_INLINE_FUNCTION static constexpr size_t static_extent(size_t r) noexcept { return extents_type::static_extent(r); } - MDSPAN_INLINE_FUNCTION constexpr index_type extent(size_t r) const noexcept { return __mapping_ref().extents().extent(r); }; - -private: - - // Can't use defaulted parameter in the __deduction_workaround template because of a bug in MSVC warning C4348. - using __impl = __deduction_workaround<std::make_index_sequence<extents_type::rank()>>; - - using __map_acc_pair_t = detail::__compressed_pair<mapping_type, accessor_type>; - -public: - - //-------------------------------------------------------------------------------- - // [mdspan.basic.cons], mdspan constructors, assignment, and destructor - -#if !MDSPAN_HAS_CXX_20 - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdspan() = default; -#else - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdspan() - requires( - // nvhpc has a bug where using just rank_dynamic() here doesn't work ... - (extents_type::rank_dynamic() > 0) && - _MDSPAN_TRAIT(std::is_default_constructible, data_handle_type) && - _MDSPAN_TRAIT(std::is_default_constructible, mapping_type) && - _MDSPAN_TRAIT(std::is_default_constructible, accessor_type) - ) = default; -#endif - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdspan(const mdspan&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdspan(mdspan&&) = default; - - MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - ((sizeof...(SizeTypes) == rank()) || (sizeof...(SizeTypes) == rank_dynamic())) && - (detail::are_valid_indices<index_type, SizeTypes...>()) && - _MDSPAN_TRAIT(std::is_constructible, mapping_type, extents_type) && - _MDSPAN_TRAIT(std::is_default_constructible, accessor_type) - ) - ) - MDSPAN_INLINE_FUNCTION - explicit constexpr mdspan(data_handle_type p, SizeTypes... dynamic_extents) - // TODO @proposal-bug shouldn't I be allowed to do `move(p)` here? - : __members(std::move(p), __map_acc_pair_t(mapping_type(extents_type(static_cast<index_type>(std::move(dynamic_extents))...)), accessor_type())) - { } - - MDSPAN_TEMPLATE_REQUIRES( - class SizeType, size_t N, - /* requires */ ( - _MDSPAN_TRAIT(std::is_convertible, const SizeType&, index_type) && - _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) && - ((N == rank()) || (N == rank_dynamic())) && - _MDSPAN_TRAIT(std::is_constructible, mapping_type, extents_type) && - _MDSPAN_TRAIT(std::is_default_constructible, accessor_type) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT(N != rank_dynamic()) - MDSPAN_INLINE_FUNCTION - constexpr mdspan(data_handle_type p, const std::array<SizeType, N>& dynamic_extents) - : __members(std::move(p), __map_acc_pair_t(mapping_type(extents_type(dynamic_extents)), accessor_type())) - { } - -#ifdef __cpp_lib_span - MDSPAN_TEMPLATE_REQUIRES( - class SizeType, size_t N, - /* requires */ ( - _MDSPAN_TRAIT(std::is_convertible, const SizeType&, index_type) && - _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) && - ((N == rank()) || (N == rank_dynamic())) && - _MDSPAN_TRAIT(std::is_constructible, mapping_type, extents_type) && - _MDSPAN_TRAIT(std::is_default_constructible, accessor_type) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT(N != rank_dynamic()) - MDSPAN_INLINE_FUNCTION - constexpr mdspan(data_handle_type p, std::span<SizeType, N> dynamic_extents) - : __members(std::move(p), __map_acc_pair_t(mapping_type(extents_type(as_const(dynamic_extents))), accessor_type())) - { } -#endif - - MDSPAN_FUNCTION_REQUIRES( - (MDSPAN_INLINE_FUNCTION constexpr), - mdspan, (data_handle_type p, const extents_type& exts), , - /* requires */ (_MDSPAN_TRAIT(std::is_default_constructible, accessor_type) && - _MDSPAN_TRAIT(std::is_constructible, mapping_type, const extents_type&)) - ) : __members(std::move(p), __map_acc_pair_t(mapping_type(exts), accessor_type())) - { } - - MDSPAN_FUNCTION_REQUIRES( - (MDSPAN_INLINE_FUNCTION constexpr), - mdspan, (data_handle_type p, const mapping_type& m), , - /* requires */ (_MDSPAN_TRAIT(std::is_default_constructible, accessor_type)) - ) : __members(std::move(p), __map_acc_pair_t(m, accessor_type())) - { } - - MDSPAN_INLINE_FUNCTION - constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a) - : __members(std::move(p), __map_acc_pair_t(m, a)) - { } - - MDSPAN_TEMPLATE_REQUIRES( - class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class OtherAccessor, - /* requires */ ( - _MDSPAN_TRAIT(std::is_constructible, mapping_type, const typename OtherLayoutPolicy::template mapping<OtherExtents>&) && - _MDSPAN_TRAIT(std::is_constructible, accessor_type, const OtherAccessor&) - ) - ) - MDSPAN_CONDITIONAL_EXPLICIT( - !_MDSPAN_TRAIT(std::is_convertible, const typename OtherLayoutPolicy::template mapping<OtherExtents>&, mapping_type) || - !_MDSPAN_TRAIT(std::is_convertible, const OtherAccessor&, accessor_type) - ) - MDSPAN_INLINE_FUNCTION - constexpr mdspan(const mdspan<OtherElementType, OtherExtents, OtherLayoutPolicy, OtherAccessor>& other) - : __members(other.__ptr_ref(), __map_acc_pair_t(other.__mapping_ref(), other.__accessor_ref())) - { - static_assert(_MDSPAN_TRAIT(std::is_constructible, data_handle_type, typename OtherAccessor::data_handle_type),"Incompatible data_handle_type for mdspan construction"); - static_assert(_MDSPAN_TRAIT(std::is_constructible, extents_type, OtherExtents),"Incompatible extents for mdspan construction"); - /* - * TODO: Check precondition - * For each rank index r of extents_type, static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r) is true. - */ - } - - /* Might need this on NVIDIA? - MDSPAN_INLINE_FUNCTION_DEFAULTED - ~mdspan() = default; - */ - - MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED mdspan& operator=(const mdspan&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED _MDSPAN_CONSTEXPR_14_DEFAULTED mdspan& operator=(mdspan&&) = default; - - - //-------------------------------------------------------------------------------- - // [mdspan.basic.mapping], mdspan mapping domain multidimensional index to access codomain element - - #if MDSPAN_USE_BRACKET_OPERATOR - MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(std::is_convertible, SizeTypes, index_type) /* && ... */) && - _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, SizeTypes) /* && ... */) && - (rank() == sizeof...(SizeTypes)) - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator[](SizeTypes... indices) const - { - return __accessor_ref().access(__ptr_ref(), __mapping_ref()(static_cast<index_type>(std::move(indices))...)); - } - #endif - - MDSPAN_TEMPLATE_REQUIRES( - class SizeType, - /* requires */ ( - _MDSPAN_TRAIT(std::is_convertible, const SizeType&, index_type) && - _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator[](const std::array< SizeType, rank()>& indices) const - { - return __impl::template __callop<reference>(*this, indices); - } - - #ifdef __cpp_lib_span - MDSPAN_TEMPLATE_REQUIRES( - class SizeType, - /* requires */ ( - _MDSPAN_TRAIT(std::is_convertible, const SizeType&, index_type) && - _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator[](std::span<SizeType, rank()> indices) const - { - return __impl::template __callop<reference>(*this, indices); - } - #endif // __cpp_lib_span - - #if !MDSPAN_USE_BRACKET_OPERATOR - MDSPAN_TEMPLATE_REQUIRES( - class Index, - /* requires */ ( - _MDSPAN_TRAIT(std::is_convertible, Index, index_type) && - _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, Index) && - extents_type::rank() == 1 - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator[](Index idx) const - { - return __accessor_ref().access(__ptr_ref(), __mapping_ref()(static_cast<index_type>(std::move(idx)))); - } - #endif - - #if MDSPAN_USE_PAREN_OPERATOR - MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - extents_type::rank() == sizeof...(SizeTypes) && - (detail::are_valid_indices<index_type, SizeTypes...>()) - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator()(SizeTypes... indices) const - { - return __accessor_ref().access(__ptr_ref(), __mapping_ref()(static_cast<index_type>(std::move(indices))...)); - } - - MDSPAN_TEMPLATE_REQUIRES( - class SizeType, - /* requires */ ( - _MDSPAN_TRAIT(std::is_convertible, const SizeType&, index_type) && - _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator()(const std::array<SizeType, rank()>& indices) const - { - return __impl::template __callop<reference>(*this, indices); - } - - #ifdef __cpp_lib_span - MDSPAN_TEMPLATE_REQUIRES( - class SizeType, - /* requires */ ( - _MDSPAN_TRAIT(std::is_convertible, const SizeType&, index_type) && - _MDSPAN_TRAIT(std::is_nothrow_constructible, index_type, const SizeType&) - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator()(std::span<SizeType, rank()> indices) const - { - return __impl::template __callop<reference>(*this, indices); - } - #endif // __cpp_lib_span - #endif // MDSPAN_USE_PAREN_OPERATOR - - MDSPAN_INLINE_FUNCTION constexpr size_type size() const noexcept { - return __impl::__size(*this); - }; - - MDSPAN_INLINE_FUNCTION constexpr bool empty() const noexcept { - return __impl::__empty(*this); - }; - - MDSPAN_INLINE_FUNCTION - friend constexpr void swap(mdspan& x, mdspan& y) noexcept { - // can't call the std::swap inside on HIP - #if !defined(_MDSPAN_HAS_HIP) && !defined(_MDSPAN_HAS_CUDA) - using std::swap; - swap(x.__ptr_ref(), y.__ptr_ref()); - swap(x.__mapping_ref(), y.__mapping_ref()); - swap(x.__accessor_ref(), y.__accessor_ref()); - #else - mdspan tmp = y; - y = x; - x = tmp; - #endif - } - - //-------------------------------------------------------------------------------- - // [mdspan.basic.domobs], mdspan observers of the domain multidimensional index space - - - MDSPAN_INLINE_FUNCTION constexpr const extents_type& extents() const noexcept { return __mapping_ref().extents(); }; - MDSPAN_INLINE_FUNCTION constexpr const data_handle_type& data_handle() const noexcept { return __ptr_ref(); }; - MDSPAN_INLINE_FUNCTION constexpr const mapping_type& mapping() const noexcept { return __mapping_ref(); }; - MDSPAN_INLINE_FUNCTION constexpr const accessor_type& accessor() const noexcept { return __accessor_ref(); }; - - //-------------------------------------------------------------------------------- - // [mdspan.basic.obs], mdspan observers of the mapping - - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() { return mapping_type::is_always_unique(); }; - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() { return mapping_type::is_always_exhaustive(); }; - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() { return mapping_type::is_always_strided(); }; - - MDSPAN_INLINE_FUNCTION constexpr bool is_unique() const { return __mapping_ref().is_unique(); }; - MDSPAN_INLINE_FUNCTION constexpr bool is_exhaustive() const { return __mapping_ref().is_exhaustive(); }; - MDSPAN_INLINE_FUNCTION constexpr bool is_strided() const { return __mapping_ref().is_strided(); }; - MDSPAN_INLINE_FUNCTION constexpr index_type stride(size_t r) const { return __mapping_ref().stride(r); }; - -private: - - detail::__compressed_pair<data_handle_type, __map_acc_pair_t> __members{}; - - MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 data_handle_type& __ptr_ref() noexcept { return __members.__first(); } - MDSPAN_FORCE_INLINE_FUNCTION constexpr data_handle_type const& __ptr_ref() const noexcept { return __members.__first(); } - MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 mapping_type& __mapping_ref() noexcept { return __members.__second().__first(); } - MDSPAN_FORCE_INLINE_FUNCTION constexpr mapping_type const& __mapping_ref() const noexcept { return __members.__second().__first(); } - MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 accessor_type& __accessor_ref() noexcept { return __members.__second().__second(); } - MDSPAN_FORCE_INLINE_FUNCTION constexpr accessor_type const& __accessor_ref() const noexcept { return __members.__second().__second(); } - - template <class, class, class, class> - friend class mdspan; - -}; - -#if defined(_MDSPAN_USE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION) -MDSPAN_TEMPLATE_REQUIRES( - class ElementType, class... SizeTypes, - /* requires */ _MDSPAN_FOLD_AND(_MDSPAN_TRAIT(std::is_convertible, SizeTypes, size_t) /* && ... */) && - (sizeof...(SizeTypes) > 0) -) -MDSPAN_DEDUCTION_GUIDE explicit mdspan(ElementType*, SizeTypes...) - -> mdspan<ElementType, ::MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<size_t, sizeof...(SizeTypes)>>; - -MDSPAN_TEMPLATE_REQUIRES( - class Pointer, - (_MDSPAN_TRAIT(std::is_pointer, std::remove_reference_t<Pointer>)) -) -MDSPAN_DEDUCTION_GUIDE mdspan(Pointer&&) -> mdspan<std::remove_pointer_t<std::remove_reference_t<Pointer>>, extents<size_t>>; - -MDSPAN_TEMPLATE_REQUIRES( - class CArray, - (_MDSPAN_TRAIT(std::is_array, CArray) && (std::rank_v<CArray> == 1)) -) -MDSPAN_DEDUCTION_GUIDE mdspan(CArray&) -> mdspan<std::remove_all_extents_t<CArray>, extents<size_t, ::std::extent_v<CArray,0>>>; - -template <class ElementType, class SizeType, size_t N> -MDSPAN_DEDUCTION_GUIDE mdspan(ElementType*, const ::std::array<SizeType, N>&) - -> mdspan<ElementType, ::MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<size_t, N>>; - -#ifdef __cpp_lib_span -template <class ElementType, class SizeType, size_t N> -MDSPAN_DEDUCTION_GUIDE mdspan(ElementType*, ::std::span<SizeType, N>) - -> mdspan<ElementType, ::MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<size_t, N>>; -#endif - -// This one is necessary because all the constructors take `data_handle_type`s, not -// `ElementType*`s, and `data_handle_type` is taken from `accessor_type::data_handle_type`, which -// seems to throw off automatic deduction guides. -template <class ElementType, class SizeType, size_t... ExtentsPack> -MDSPAN_DEDUCTION_GUIDE mdspan(ElementType*, const extents<SizeType, ExtentsPack...>&) - -> mdspan<ElementType, ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents<SizeType, ExtentsPack...>>; - -template <class ElementType, class MappingType> -MDSPAN_DEDUCTION_GUIDE mdspan(ElementType*, const MappingType&) - -> mdspan<ElementType, typename MappingType::extents_type, typename MappingType::layout_type>; - -template <class MappingType, class AccessorType> -MDSPAN_DEDUCTION_GUIDE mdspan(const typename AccessorType::data_handle_type, const MappingType&, const AccessorType&) - -> mdspan<typename AccessorType::element_type, typename MappingType::extents_type, typename MappingType::layout_type, AccessorType>; -#endif - -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/no_unique_address.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/no_unique_address.hpp deleted file mode 100644 index 36e64ee24dbb7166ac5da069bbbfbc4347026993..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/no_unique_address.hpp +++ /dev/null @@ -1,97 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER -#pragma once - -#include "macros.hpp" -#include "trait_backports.hpp" - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -namespace detail { - -//============================================================================== - -template <class _T, size_t _Disambiguator = 0, class _Enable = void> -struct __no_unique_address_emulation { - using __stored_type = _T; - _T __v; - MDSPAN_FORCE_INLINE_FUNCTION constexpr _T const &__ref() const noexcept { - return __v; - } - MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T &__ref() noexcept { - return __v; - } -}; - -// Empty case -// This doesn't work if _T is final, of course, but we're not using anything -// like that currently. That kind of thing could be added pretty easily though -template <class _T, size_t _Disambiguator> -struct __no_unique_address_emulation< - _T, _Disambiguator, - std::enable_if_t<_MDSPAN_TRAIT(std::is_empty, _T) && - // If the type isn't trivially destructible, its destructor - // won't be called at the right time, so don't use this - // specialization - _MDSPAN_TRAIT(std::is_trivially_destructible, _T)>> : -#ifdef _MDSPAN_COMPILER_MSVC - // MSVC doesn't allow you to access public static member functions of a type - // when you *happen* to privately inherit from that type. - protected -#else - // But we still want this to be private if possible so that we don't accidentally - // access members of _T directly rather than calling __ref() first, which wouldn't - // work if _T happens to be stateful and thus we're using the unspecialized definition - // of __no_unique_address_emulation above. - private -#endif - _T { - using __stored_type = _T; - MDSPAN_FORCE_INLINE_FUNCTION constexpr _T const &__ref() const noexcept { - return *static_cast<_T const *>(this); - } - MDSPAN_FORCE_INLINE_FUNCTION _MDSPAN_CONSTEXPR_14 _T &__ref() noexcept { - return *static_cast<_T *>(this); - } - - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr __no_unique_address_emulation() noexcept = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr __no_unique_address_emulation( - __no_unique_address_emulation const &) noexcept = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr __no_unique_address_emulation( - __no_unique_address_emulation &&) noexcept = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - _MDSPAN_CONSTEXPR_14_DEFAULTED __no_unique_address_emulation & - operator=(__no_unique_address_emulation const &) noexcept = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - _MDSPAN_CONSTEXPR_14_DEFAULTED __no_unique_address_emulation & - operator=(__no_unique_address_emulation &&) noexcept = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - ~__no_unique_address_emulation() noexcept = default; - - // Explicitly make this not a reference so that the copy or move - // constructor still gets called. - MDSPAN_INLINE_FUNCTION - explicit constexpr __no_unique_address_emulation(_T const& __v) noexcept : _T(__v) {} - MDSPAN_INLINE_FUNCTION - explicit constexpr __no_unique_address_emulation(_T&& __v) noexcept : _T(::std::move(__v)) {} -}; - -//============================================================================== - -} // end namespace detail -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/trait_backports.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/trait_backports.hpp deleted file mode 100644 index 4933dd9934ea0a967ff46b5afc303a1431df6748..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/trait_backports.hpp +++ /dev/null @@ -1,132 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER -#ifndef MDSPAN_INCLUDE_EXPERIMENTAL_BITS_TRAIT_BACKPORTS_HPP_ -#define MDSPAN_INCLUDE_EXPERIMENTAL_BITS_TRAIT_BACKPORTS_HPP_ - -#include "macros.hpp" -#include "config.hpp" - -#include <type_traits> -#include <utility> // integer_sequence - -//============================================================================== -// <editor-fold desc="Variable template trait backports (e.g., is_void_v)"> {{{1 - -#ifdef _MDSPAN_NEEDS_TRAIT_VARIABLE_TEMPLATE_BACKPORTS - -#if _MDSPAN_USE_VARIABLE_TEMPLATES -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { - -#define _MDSPAN_BACKPORT_TRAIT(TRAIT) \ - template <class... Args> _MDSPAN_INLINE_VARIABLE constexpr auto TRAIT##_v = TRAIT<Args...>::value; - -_MDSPAN_BACKPORT_TRAIT(is_assignable) -_MDSPAN_BACKPORT_TRAIT(is_constructible) -_MDSPAN_BACKPORT_TRAIT(is_convertible) -_MDSPAN_BACKPORT_TRAIT(is_default_constructible) -_MDSPAN_BACKPORT_TRAIT(is_trivially_destructible) -_MDSPAN_BACKPORT_TRAIT(is_same) -_MDSPAN_BACKPORT_TRAIT(is_empty) -_MDSPAN_BACKPORT_TRAIT(is_void) - -#undef _MDSPAN_BACKPORT_TRAIT - -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE - -#endif // _MDSPAN_USE_VARIABLE_TEMPLATES - -#endif // _MDSPAN_NEEDS_TRAIT_VARIABLE_TEMPLATE_BACKPORTS - -// </editor-fold> end Variable template trait backports (e.g., is_void_v) }}}1 -//============================================================================== - -//============================================================================== -// <editor-fold desc="integer sequence (ugh...)"> {{{1 - -#if !defined(_MDSPAN_USE_INTEGER_SEQUENCE) || !_MDSPAN_USE_INTEGER_SEQUENCE - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { - -template <class T, T... Vals> -struct integer_sequence { - static constexpr size_t size() noexcept { return sizeof...(Vals); } - using value_type = T; -}; - -template <size_t... Vals> -using index_sequence = std::integer_sequence<size_t, Vals...>; - -namespace __detail { - -template <class T, T N, T I, class Result> -struct __make_int_seq_impl; - -template <class T, T N, T... Vals> -struct __make_int_seq_impl<T, N, N, integer_sequence<T, Vals...>> -{ - using type = integer_sequence<T, Vals...>; -}; - -template <class T, T N, T I, T... Vals> -struct __make_int_seq_impl< - T, N, I, integer_sequence<T, Vals...> -> : __make_int_seq_impl<T, N, I+1, integer_sequence<T, Vals..., I>> -{ }; - -} // end namespace __detail - -template <class T, T N> -using make_integer_sequence = typename __detail::__make_int_seq_impl<T, N, 0, integer_sequence<T>>::type; - -template <size_t N> -using make_index_sequence = typename __detail::__make_int_seq_impl<size_t, N, 0, integer_sequence<size_t>>::type; - -template <class... T> -using index_sequence_for = make_index_sequence<sizeof...(T)>; - -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE - -#endif - -// </editor-fold> end integer sequence (ugh...) }}}1 -//============================================================================== - -//============================================================================== -// <editor-fold desc="standard trait aliases"> {{{1 - -#if !defined(_MDSPAN_USE_STANDARD_TRAIT_ALIASES) || !_MDSPAN_USE_STANDARD_TRAIT_ALIASES - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { - -#define _MDSPAN_BACKPORT_TRAIT_ALIAS(TRAIT) \ - template <class... Args> using TRAIT##_t = typename TRAIT<Args...>::type; - -_MDSPAN_BACKPORT_TRAIT_ALIAS(remove_cv) -_MDSPAN_BACKPORT_TRAIT_ALIAS(remove_reference) - -template <bool _B, class _T=void> -using enable_if_t = typename enable_if<_B, _T>::type; - -#undef _MDSPAN_BACKPORT_TRAIT_ALIAS - -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE - -#endif - -// </editor-fold> end standard trait aliases }}}1 -//============================================================================== - -#endif //MDSPAN_INCLUDE_EXPERIMENTAL_BITS_TRAIT_BACKPORTS_HPP_ diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/type_list.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/type_list.hpp deleted file mode 100644 index deca7c15d095857a805fa00cbd1947ce8c434d65..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/type_list.hpp +++ /dev/null @@ -1,87 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER -#include "macros.hpp" - -#include "trait_backports.hpp" // make_index_sequence - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { - -//============================================================================== - -namespace detail { - -template <class... _Ts> struct __type_list { static constexpr auto __size = sizeof...(_Ts); }; - -// Implementation of type_list at() that's heavily optimized for small typelists -template <size_t, class> struct __type_at; -template <size_t, class _Seq, class=std::make_index_sequence<_Seq::__size>> struct __type_at_large_impl; - -template <size_t _I, size_t _Idx, class _T> -struct __type_at_entry { }; - -template <class _Result> -struct __type_at_assign_op_ignore_rest { - template <class _T> - __type_at_assign_op_ignore_rest<_Result> operator=(_T&&); - using type = _Result; -}; - -struct __type_at_assign_op_impl { - template <size_t _I, size_t _Idx, class _T> - __type_at_assign_op_impl operator=(__type_at_entry<_I, _Idx, _T>&&); - template <size_t _I, class _T> - __type_at_assign_op_ignore_rest<_T> operator=(__type_at_entry<_I, _I, _T>&&); -}; - -template <size_t _I, class... _Ts, size_t... _Idxs> -struct __type_at_large_impl<_I, __type_list<_Ts...>, std::integer_sequence<size_t, _Idxs...>> - : decltype( - _MDSPAN_FOLD_ASSIGN_LEFT(__type_at_assign_op_impl{}, /* = ... = */ __type_at_entry<_I, _Idxs, _Ts>{}) - ) -{ }; - -template <size_t _I, class... _Ts> -struct __type_at<_I, __type_list<_Ts...>> - : __type_at_large_impl<_I, __type_list<_Ts...>> -{ }; - -template <class _T0, class... _Ts> -struct __type_at<0, __type_list<_T0, _Ts...>> { - using type = _T0; -}; - -template <class _T0, class _T1, class... _Ts> -struct __type_at<1, __type_list<_T0, _T1, _Ts...>> { - using type = _T1; -}; - -template <class _T0, class _T1, class _T2, class... _Ts> -struct __type_at<2, __type_list<_T0, _T1, _T2, _Ts...>> { - using type = _T2; -}; - -template <class _T0, class _T1, class _T2, class _T3, class... _Ts> -struct __type_at<3, __type_list<_T0, _T1, _T2, _T3, _Ts...>> { - using type = _T3; -}; - - -} // namespace detail - -//============================================================================== - -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE - diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/utility.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/utility.hpp deleted file mode 100644 index ca821176f875e4e650984a4d674e0a64dede53af..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p0009_bits/utility.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include <cstddef> -#include <type_traits> - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -namespace detail { - -// type alias used for rank-based tag dispatch -// -// this is used to enable alternatives to constexpr if when building for C++14 -// -template <std::size_t N> -using with_rank = std::integral_constant<std::size_t, N>; - -template <class I1, class I2> -constexpr bool common_integral_compare(I1 x, I2 y) -{ - static_assert(std::is_integral<I1>::value and - std::is_integral<I2>::value, ""); - - using I = std::common_type_t<I1, I2>; - return static_cast<I>(x) == static_cast<I>(y); -} - -template <class T1, class T2, class F> -constexpr bool rankwise_equal(with_rank<0>, const T1&, const T2&, F) -{ - return true; -} -template <std::size_t N, class T1, class T2, class F> -constexpr bool rankwise_equal(with_rank<N>, const T1& x, const T2& y, F func) -{ - bool match = true; - - for (std::size_t r = 0; r < N; r++) { - match = match && common_integral_compare(func(x, r), func(y, r)); - } - - return match; -} - -constexpr struct -{ - template <class T, class I> - constexpr auto operator()(const T& x, I i) const - { - return x.extent(i); - } -} extent; - -constexpr struct -{ - template <class T, class I> - constexpr auto operator()(const T& x, I i) const - { - return x.stride(i); - } -} stride; - -} // namespace detail - -constexpr struct mdspan_non_standard_tag { -} mdspan_non_standard; - -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p1684_bits/mdarray.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p1684_bits/mdarray.hpp deleted file mode 100644 index bdc5925f715190b2d7163ec75e0c5956df706df9..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p1684_bits/mdarray.hpp +++ /dev/null @@ -1,460 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER - -#pragma once - -#include "../mdspan" -#include <cassert> -#include <vector> - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -namespace MDSPAN_IMPL_PROPOSED_NAMESPACE { - -namespace { - template<class Extents> - struct size_of_extents; - - template<class IndexType, size_t ... Extents> - struct size_of_extents<extents<IndexType, Extents...>> { - constexpr static size_t value() { - size_t size = 1; - for(size_t r=0; r<extents<IndexType, Extents...>::rank(); r++) - size *= extents<IndexType, Extents...>::static_extent(r); - return size; - } - }; -} - -namespace { - template<class C> - struct container_is_array : std::false_type { - template<class M> - static constexpr C construct(const M& m) { return C(m.required_span_size()); } - }; - template<class T, size_t N> - struct container_is_array<std::array<T,N>> : std::true_type { - template<class M> - static constexpr std::array<T,N> construct(const M&) { return std::array<T,N>(); } - }; -} - -template < - class ElementType, - class Extents, - class LayoutPolicy = layout_right, - class Container = std::vector<ElementType> -> -class mdarray { -private: - static_assert(::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::__is_extents_v<Extents>, - MDSPAN_IMPL_PROPOSED_NAMESPACE_STRING "::mdspan's Extents template parameter must be a specialization of " MDSPAN_IMPL_STANDARD_NAMESPACE_STRING "::extents."); - -public: - - //-------------------------------------------------------------------------------- - // Domain and codomain types - - using extents_type = Extents; - using layout_type = LayoutPolicy; - using container_type = Container; - using mapping_type = typename layout_type::template mapping<extents_type>; - using element_type = ElementType; - using mdspan_type = mdspan<element_type, extents_type, layout_type>; - using const_mdspan_type = mdspan<const element_type, extents_type, layout_type>; - using value_type = std::remove_cv_t<element_type>; - using index_type = typename Extents::index_type; - using size_type = typename Extents::size_type; - using rank_type = typename Extents::rank_type; - using pointer = typename container_type::pointer; - using reference = typename container_type::reference; - using const_pointer = typename container_type::const_pointer; - using const_reference = typename container_type::const_reference; - -public: - - //-------------------------------------------------------------------------------- - // [mdspan.basic.cons], mdspan constructors, assignment, and destructor - -#if !(MDSPAN_HAS_CXX_20) - MDSPAN_FUNCTION_REQUIRES( - (MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr), - mdarray, (), , - /* requires */ (extents_type::rank_dynamic()!=0)) {} -#else - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray() requires(extents_type::rank_dynamic()!=0) = default; -#endif - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray(const mdarray&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray(mdarray&&) = default; - - // Constructors for container types constructible from a size - MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - (::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::are_valid_indices<index_type, SizeTypes...>()) && - _MDSPAN_TRAIT( std::is_constructible, extents_type, SizeTypes...) && - _MDSPAN_TRAIT( std::is_constructible, mapping_type, extents_type) && - (_MDSPAN_TRAIT( std::is_constructible, container_type, size_t) || - container_is_array<container_type>::value) && - (extents_type::rank()>0 || extents_type::rank_dynamic()==0) - ) - ) - MDSPAN_INLINE_FUNCTION - explicit constexpr mdarray(SizeTypes... dynamic_extents) - : map_(extents_type(dynamic_extents...)), ctr_(container_is_array<container_type>::construct(map_)) - { } - - MDSPAN_FUNCTION_REQUIRES( - (MDSPAN_INLINE_FUNCTION constexpr), - mdarray, (const extents_type& exts), , - /* requires */ ((_MDSPAN_TRAIT( std::is_constructible, container_type, size_t) || - container_is_array<container_type>::value) && - _MDSPAN_TRAIT( std::is_constructible, mapping_type, extents_type)) - ) : map_(exts), ctr_(container_is_array<container_type>::construct(map_)) - { } - - MDSPAN_FUNCTION_REQUIRES( - (MDSPAN_INLINE_FUNCTION constexpr), - mdarray, (const mapping_type& m), , - /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, size_t) || - container_is_array<container_type>::value) - ) : map_(m), ctr_(container_is_array<container_type>::construct(map_)) - { } - - MDSPAN_FUNCTION_REQUIRES( - (MDSPAN_INLINE_FUNCTION constexpr), - mdarray, (const extents_type& exts, const container_type& ctr), , - /* requires */ (_MDSPAN_TRAIT( std::is_constructible, mapping_type, extents_type)) - ) : map_(exts), ctr_(ctr) - { assert(ctr.size() >= static_cast<size_t>(map_.required_span_size())); } - - constexpr mdarray(const mapping_type& m, const container_type& ctr) - : map_(m), ctr_(ctr) - { assert(ctr.size() >= static_cast<size_t>(map_.required_span_size())); } - - MDSPAN_FUNCTION_REQUIRES( - (MDSPAN_INLINE_FUNCTION constexpr), - mdarray, (const extents_type& exts, container_type&& ctr), , - /* requires */ (_MDSPAN_TRAIT( std::is_constructible, mapping_type, extents_type)) - ) : map_(exts), ctr_(std::move(ctr)) - { assert(ctr_.size() >= static_cast<size_t>(map_.required_span_size())); } - - constexpr mdarray(const mapping_type& m, container_type&& ctr) - : map_(m), ctr_(std::move(ctr)) - { assert(ctr_.size() >= static_cast<size_t>(map_.required_span_size())); } - - - MDSPAN_TEMPLATE_REQUIRES( - class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class OtherContainer, - /* requires */ ( - _MDSPAN_TRAIT( std::is_constructible, mapping_type, typename OtherLayoutPolicy::template mapping<OtherExtents>) && - _MDSPAN_TRAIT( std::is_constructible, container_type, OtherContainer) - ) - ) - MDSPAN_INLINE_FUNCTION - constexpr mdarray(const mdarray<OtherElementType, OtherExtents, OtherLayoutPolicy, OtherContainer>& other) - : map_(other.mapping()), ctr_(other.container()) - { - static_assert( std::is_constructible<extents_type, OtherExtents>::value, ""); - } - - // Constructors for container types constructible from a size and allocator - MDSPAN_TEMPLATE_REQUIRES( - class Alloc, - /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, size_t, Alloc) && - _MDSPAN_TRAIT( std::is_constructible, mapping_type, extents_type)) - ) - MDSPAN_INLINE_FUNCTION - constexpr mdarray(const extents_type& exts, const Alloc& a) - : map_(exts), ctr_(map_.required_span_size(), a) - { } - - MDSPAN_TEMPLATE_REQUIRES( - class Alloc, - /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, size_t, Alloc)) - ) - MDSPAN_INLINE_FUNCTION - constexpr mdarray(const mapping_type& map, const Alloc& a) - : map_(map), ctr_(map_.required_span_size(), a) - { } - - // Constructors for container types constructible from a container and allocator - MDSPAN_TEMPLATE_REQUIRES( - class Alloc, - /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, container_type, Alloc) && - _MDSPAN_TRAIT( std::is_constructible, mapping_type, extents_type)) - ) - MDSPAN_INLINE_FUNCTION - constexpr mdarray(const extents_type& exts, const container_type& ctr, const Alloc& a) - : map_(exts), ctr_(ctr, a) - { assert(ctr_.size() >= static_cast<size_t>(map_.required_span_size())); } - - MDSPAN_TEMPLATE_REQUIRES( - class Alloc, - /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, size_t, Alloc)) - ) - MDSPAN_INLINE_FUNCTION - constexpr mdarray(const mapping_type& map, const container_type& ctr, const Alloc& a) - : map_(map), ctr_(ctr, a) - { assert(ctr_.size() >= static_cast<size_t>(map_.required_span_size())); } - - MDSPAN_TEMPLATE_REQUIRES( - class Alloc, - /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, container_type, Alloc) && - _MDSPAN_TRAIT( std::is_constructible, mapping_type, extents_type)) - ) - MDSPAN_INLINE_FUNCTION - constexpr mdarray(const extents_type& exts, container_type&& ctr, const Alloc& a) - : map_(exts), ctr_(std::move(ctr), a) - { assert(ctr_.size() >= static_cast<size_t>(map_.required_span_size())); } - - MDSPAN_TEMPLATE_REQUIRES( - class Alloc, - /* requires */ (_MDSPAN_TRAIT( std::is_constructible, container_type, size_t, Alloc)) - ) - MDSPAN_INLINE_FUNCTION - constexpr mdarray(const mapping_type& map, container_type&& ctr, const Alloc& a) - : map_(map), ctr_(std::move(ctr), a) - { assert(ctr_.size() >= map_.required_span_size()); } - - MDSPAN_TEMPLATE_REQUIRES( - class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class OtherContainer, class Alloc, - /* requires */ ( - _MDSPAN_TRAIT( std::is_constructible, mapping_type, typename OtherLayoutPolicy::template mapping<OtherExtents>) && - _MDSPAN_TRAIT( std::is_constructible, container_type, OtherContainer, Alloc) - ) - ) - MDSPAN_INLINE_FUNCTION - constexpr mdarray(const mdarray<OtherElementType, OtherExtents, OtherLayoutPolicy, OtherContainer>& other, const Alloc& a) - : map_(other.mapping()), ctr_(other.container(), a) - { - static_assert( std::is_constructible<extents_type, OtherExtents>::value, ""); - } - - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray& operator= (const mdarray&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mdarray& operator= (mdarray&&) = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED - ~mdarray() = default; - - //-------------------------------------------------------------------------------- - // [mdspan.basic.mapping], mdspan mapping domain multidimensional index to access codomain element - - #if MDSPAN_USE_BRACKET_OPERATOR - MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - _MDSPAN_FOLD_AND(_MDSPAN_TRAIT( std::is_convertible, SizeTypes, index_type) /* && ... */) && - extents_type::rank() == sizeof...(SizeTypes) - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr const_reference operator[](SizeTypes... indices) const noexcept - { - return ctr_[map_(static_cast<index_type>(std::move(indices))...)]; - } - - MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - _MDSPAN_FOLD_AND(_MDSPAN_TRAIT( std::is_convertible, SizeTypes, index_type) /* && ... */) && - extents_type::rank() == sizeof...(SizeTypes) - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator[](SizeTypes... indices) noexcept - { - return ctr_[map_(static_cast<index_type>(std::move(indices))...)]; - } - #endif - -#if 0 - MDSPAN_TEMPLATE_REQUIRES( - class SizeType, size_t N, - /* requires */ ( - _MDSPAN_TRAIT( std::is_convertible, SizeType, index_type) && - N == extents_type::rank() - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr const_reference operator[](const std::array<SizeType, N>& indices) const noexcept - { - return __impl::template __callop<reference>(*this, indices); - } - - MDSPAN_TEMPLATE_REQUIRES( - class SizeType, size_t N, - /* requires */ ( - _MDSPAN_TRAIT( std::is_convertible, SizeType, index_type) && - N == extents_type::rank() - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator[](const std::array<SizeType, N>& indices) noexcept - { - return __impl::template __callop<reference>(*this, indices); - } -#endif - - - #if MDSPAN_USE_PAREN_OPERATOR - MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - (::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::are_valid_indices<index_type, SizeTypes...>()) && - extents_type::rank() == sizeof...(SizeTypes) - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr const_reference operator()(SizeTypes... indices) const noexcept - { - return ctr_[map_(static_cast<index_type>(std::move(indices))...)]; - } - MDSPAN_TEMPLATE_REQUIRES( - class... SizeTypes, - /* requires */ ( - (::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::are_valid_indices<index_type, SizeTypes...>()) && - extents_type::rank() == sizeof...(SizeTypes) - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator()(SizeTypes... indices) noexcept - { - return ctr_[map_(static_cast<index_type>(std::move(indices))...)]; - } - -#if 0 - MDSPAN_TEMPLATE_REQUIRES( - class SizeType, size_t N, - /* requires */ ( - _MDSPAN_TRAIT( std::is_convertible, SizeType, index_type) && - N == extents_type::rank() - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr const_reference operator()(const std::array<SizeType, N>& indices) const noexcept - { - return __impl::template __callop<reference>(*this, indices); - } - - MDSPAN_TEMPLATE_REQUIRES( - class SizeType, size_t N, - /* requires */ ( - _MDSPAN_TRAIT( std::is_convertible, SizeType, index_type) && - N == extents_type::rank() - ) - ) - MDSPAN_FORCE_INLINE_FUNCTION - constexpr reference operator()(const std::array<SizeType, N>& indices) noexcept - { - return __impl::template __callop<reference>(*this, indices); - } -#endif - #endif - - MDSPAN_INLINE_FUNCTION constexpr pointer data() noexcept { return ctr_.data(); }; - MDSPAN_INLINE_FUNCTION constexpr const_pointer data() const noexcept { return ctr_.data(); }; - MDSPAN_INLINE_FUNCTION constexpr container_type& container() noexcept { return ctr_; }; - MDSPAN_INLINE_FUNCTION constexpr const container_type& container() const noexcept { return ctr_; }; - - //-------------------------------------------------------------------------------- - // [mdspan.basic.domobs], mdspan observers of the domain multidimensional index space - - MDSPAN_INLINE_FUNCTION static constexpr rank_type rank() noexcept { return extents_type::rank(); } - MDSPAN_INLINE_FUNCTION static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); } - MDSPAN_INLINE_FUNCTION static constexpr size_t static_extent(size_t r) noexcept { return extents_type::static_extent(r); } - - MDSPAN_INLINE_FUNCTION constexpr const extents_type& extents() const noexcept { return map_.extents(); }; - MDSPAN_INLINE_FUNCTION constexpr index_type extent(size_t r) const noexcept { return map_.extents().extent(r); }; - MDSPAN_INLINE_FUNCTION constexpr index_type size() const noexcept { -// return __impl::__size(*this); - return ctr_.size(); - }; - - - //-------------------------------------------------------------------------------- - // [mdspan.basic.obs], mdspan observers of the mapping - - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { return mapping_type::is_always_unique(); }; - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { return mapping_type::is_always_exhaustive(); }; - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { return mapping_type::is_always_strided(); }; - - MDSPAN_INLINE_FUNCTION constexpr const mapping_type& mapping() const noexcept { return map_; }; - MDSPAN_INLINE_FUNCTION constexpr bool is_unique() const noexcept { return map_.is_unique(); }; - MDSPAN_INLINE_FUNCTION constexpr bool is_exhaustive() const noexcept { return map_.is_exhaustive(); }; - MDSPAN_INLINE_FUNCTION constexpr bool is_strided() const noexcept { return map_.is_strided(); }; - MDSPAN_INLINE_FUNCTION constexpr index_type stride(size_t r) const { return map_.stride(r); }; - - // Converstion to mdspan - MDSPAN_TEMPLATE_REQUIRES( - class OtherElementType, class OtherExtents, - class OtherLayoutType, class OtherAccessorType, - /* requires */ ( - _MDSPAN_TRAIT(std::is_assignable, - mdspan<OtherElementType, OtherExtents, OtherLayoutType, OtherAccessorType>, - mdspan_type) - ) - ) - constexpr operator mdspan<OtherElementType, OtherExtents, OtherLayoutType, OtherAccessorType> () { - return mdspan_type(data(), map_); - } - - MDSPAN_TEMPLATE_REQUIRES( - class OtherElementType, class OtherExtents, - class OtherLayoutType, class OtherAccessorType, - /* requires */ ( - _MDSPAN_TRAIT(std::is_assignable, - mdspan<OtherElementType, OtherExtents, OtherLayoutType, OtherAccessorType>, - const_mdspan_type) - ) - ) - constexpr operator mdspan<OtherElementType, OtherExtents, OtherLayoutType, OtherAccessorType> () const { - return const_mdspan_type(data(), map_); - } - - MDSPAN_TEMPLATE_REQUIRES( - class OtherAccessorType = default_accessor<element_type>, - /* requires */ ( - _MDSPAN_TRAIT(std::is_assignable, mdspan_type, - mdspan<element_type, extents_type, layout_type, OtherAccessorType>) - ) - ) - constexpr mdspan<element_type, extents_type, layout_type, OtherAccessorType> - to_mdspan(const OtherAccessorType& a = default_accessor<element_type>()) { - return mdspan<element_type, extents_type, layout_type, OtherAccessorType>(data(), map_, a); - } - - MDSPAN_TEMPLATE_REQUIRES( - class OtherAccessorType = default_accessor<const element_type>, - /* requires */ ( - _MDSPAN_TRAIT(std::is_assignable, const_mdspan_type, - mdspan<const element_type, extents_type, layout_type, OtherAccessorType>) - ) - ) - constexpr mdspan<const element_type, extents_type, layout_type, OtherAccessorType> - to_mdspan(const OtherAccessorType& a = default_accessor<const element_type>()) const { - return mdspan<const element_type, extents_type, layout_type, OtherAccessorType>(data(), map_, a); - } - -private: - mapping_type map_; - container_type ctr_; - - template <class, class, class, class> - friend class mdarray; -}; - - -} // end namespace MDSPAN_IMPL_PROPOSED_NAMESPACE -} // end namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p2389_bits/dims.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p2389_bits/dims.hpp deleted file mode 100644 index 00045215c489bfaa04bd0d7967a85b49559fb714..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p2389_bits/dims.hpp +++ /dev/null @@ -1,28 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER - -#pragma once - -// backward compatibility import into experimental -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -namespace MDSPAN_IMPL_PROPOSED_NAMESPACE { - -template< ::std::size_t Rank, class IndexType = std::size_t> -using dims = - :: MDSPAN_IMPL_STANDARD_NAMESPACE :: dextents<IndexType, Rank>; - -} // namespace MDSPAN_IMPL_PROPOSED_NAMESPACE -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p2630_bits/strided_slice.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p2630_bits/strided_slice.hpp deleted file mode 100644 index 89ba8202fb16a090bfa9352a4dcf7041cf53c90f..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p2630_bits/strided_slice.hpp +++ /dev/null @@ -1,48 +0,0 @@ - -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER - -#pragma once - -#include <type_traits> - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { - -namespace { - template<class T> - struct __mdspan_is_integral_constant: std::false_type {}; - - template<class T, T val> - struct __mdspan_is_integral_constant<std::integral_constant<T,val>>: std::true_type {}; -} - -// Slice Specifier allowing for strides and compile time extent -template <class OffsetType, class ExtentType, class StrideType> -struct strided_slice { - using offset_type = OffsetType; - using extent_type = ExtentType; - using stride_type = StrideType; - - _MDSPAN_NO_UNIQUE_ADDRESS OffsetType offset{}; - _MDSPAN_NO_UNIQUE_ADDRESS ExtentType extent{}; - _MDSPAN_NO_UNIQUE_ADDRESS StrideType stride{}; - - static_assert(std::is_integral_v<OffsetType> || __mdspan_is_integral_constant<OffsetType>::value); - static_assert(std::is_integral_v<ExtentType> || __mdspan_is_integral_constant<ExtentType>::value); - static_assert(std::is_integral_v<StrideType> || __mdspan_is_integral_constant<StrideType>::value); -}; - -} // MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p2630_bits/submdspan.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p2630_bits/submdspan.hpp deleted file mode 100644 index abddd0b59df170f2b16f7e5d301e45378a42bdee..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p2630_bits/submdspan.hpp +++ /dev/null @@ -1,40 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER - -#pragma once - -#include "submdspan_extents.hpp" -#include "submdspan_mapping.hpp" - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -template <class ElementType, class Extents, class LayoutPolicy, - class AccessorPolicy, class... SliceSpecifiers> -MDSPAN_INLINE_FUNCTION -constexpr auto -submdspan(const mdspan<ElementType, Extents, LayoutPolicy, AccessorPolicy> &src, - SliceSpecifiers... slices) { - const auto sub_submdspan_mapping_result = submdspan_mapping(src.mapping(), slices...); - // NVCC has a problem with the deduction so lets figure out the type - using sub_mapping_t = std::remove_cv_t<decltype(sub_submdspan_mapping_result.mapping)>; - using sub_extents_t = typename sub_mapping_t::extents_type; - using sub_layout_t = typename sub_mapping_t::layout_type; - using sub_accessor_t = typename AccessorPolicy::offset_policy; - return mdspan<ElementType, sub_extents_t, sub_layout_t, sub_accessor_t>( - src.accessor().offset(src.data_handle(), sub_submdspan_mapping_result.offset), - sub_submdspan_mapping_result.mapping, - sub_accessor_t(src.accessor())); -} -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p2630_bits/submdspan_extents.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p2630_bits/submdspan_extents.hpp deleted file mode 100644 index c3b2f78fb998cb1a3c77a9cac8738085d81cbbaf..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p2630_bits/submdspan_extents.hpp +++ /dev/null @@ -1,321 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER - -#pragma once - -#include <tuple> - -#include "strided_slice.hpp" -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -namespace detail { - -// Mapping from submapping ranks to srcmapping ranks -// InvMapRank is an index_sequence, which we build recursively -// to contain the mapped indices. -// end of recursion specialization containing the final index_sequence -template <size_t Counter, size_t... MapIdxs> -MDSPAN_INLINE_FUNCTION -constexpr auto inv_map_rank(std::integral_constant<size_t, Counter>, std::index_sequence<MapIdxs...>) { - return std::index_sequence<MapIdxs...>(); -} - -// specialization reducing rank by one (i.e., integral slice specifier) -template<size_t Counter, class Slice, class... SliceSpecifiers, size_t... MapIdxs> -MDSPAN_INLINE_FUNCTION -constexpr auto inv_map_rank(std::integral_constant<size_t, Counter>, std::index_sequence<MapIdxs...>, Slice, - SliceSpecifiers... slices) { - using next_idx_seq_t = std::conditional_t<std::is_convertible_v<Slice, size_t>, - std::index_sequence<MapIdxs...>, - std::index_sequence<MapIdxs..., Counter>>; - - return inv_map_rank(std::integral_constant<size_t,Counter + 1>(), next_idx_seq_t(), - slices...); -} - -// Helper for identifying strided_slice -template <class T> struct is_strided_slice : std::false_type {}; - -template <class OffsetType, class ExtentType, class StrideType> -struct is_strided_slice< - strided_slice<OffsetType, ExtentType, StrideType>> : std::true_type {}; - -// first_of(slice): getting begin of slice specifier range -MDSPAN_TEMPLATE_REQUIRES( - class Integral, - /* requires */(std::is_convertible_v<Integral, size_t>) -) -MDSPAN_INLINE_FUNCTION -constexpr Integral first_of(const Integral &i) { - return i; -} - -MDSPAN_INLINE_FUNCTION -constexpr std::integral_constant<size_t, 0> -first_of(const ::MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent_t &) { - return std::integral_constant<size_t, 0>(); -} - -MDSPAN_TEMPLATE_REQUIRES( - class Slice, - /* requires */(std::is_convertible_v<Slice, std::tuple<size_t, size_t>>) -) -MDSPAN_INLINE_FUNCTION -constexpr auto first_of(const Slice &i) { - return std::get<0>(i); -} - -template <class OffsetType, class ExtentType, class StrideType> -MDSPAN_INLINE_FUNCTION -constexpr OffsetType -first_of(const strided_slice<OffsetType, ExtentType, StrideType> &r) { - return r.offset; -} - -// last_of(slice): getting end of slice specifier range -// We need however not just the slice but also the extents -// of the original view and which rank from the extents. -// This is needed in the case of slice being full_extent_t. -MDSPAN_TEMPLATE_REQUIRES( - size_t k, class Extents, class Integral, - /* requires */(std::is_convertible_v<Integral, size_t>) -) -MDSPAN_INLINE_FUNCTION -constexpr Integral - last_of(std::integral_constant<size_t, k>, const Extents &, const Integral &i) { - return i; -} - -MDSPAN_TEMPLATE_REQUIRES( - size_t k, class Extents, class Slice, - /* requires */(std::is_convertible_v<Slice, std::tuple<size_t, size_t>>) -) -MDSPAN_INLINE_FUNCTION -constexpr auto last_of(std::integral_constant<size_t, k>, const Extents &, - const Slice &i) { - return std::get<1>(i); -} - -// Suppress spurious warning with NVCC about no return statement. -// This is a known issue in NVCC and NVC++ -// Depending on the CUDA and GCC version we need both the builtin -// and the diagnostic push. I tried really hard to find something shorter -// but no luck ... -#if defined __NVCC__ - #ifdef __NVCC_DIAG_PRAGMA_SUPPORT__ - #pragma nv_diagnostic push - #pragma nv_diag_suppress = implicit_return_from_non_void_function - #else - #ifdef __CUDA_ARCH__ - #pragma diagnostic push - #pragma diag_suppress implicit_return_from_non_void_function - #endif - #endif -#elif defined __NVCOMPILER - #pragma diagnostic push - #pragma diag_suppress = implicit_return_from_non_void_function -#endif -template <size_t k, class Extents> -MDSPAN_INLINE_FUNCTION -constexpr auto last_of(std::integral_constant<size_t, k>, const Extents &ext, - ::MDSPAN_IMPL_STANDARD_NAMESPACE::full_extent_t) { - if constexpr (Extents::static_extent(k) == dynamic_extent) { - return ext.extent(k); - } else { - return std::integral_constant<size_t, Extents::static_extent(k)>(); - } -#if defined(__NVCC__) && !defined(__CUDA_ARCH__) && defined(__GNUC__) - // Even with CUDA_ARCH protection this thing warns about calling host function - __builtin_unreachable(); -#endif -} -#if defined __NVCC__ - #ifdef __NVCC_DIAG_PRAGMA_SUPPORT__ - #pragma nv_diagnostic pop - #else - #ifdef __CUDA_ARCH__ - #pragma diagnostic pop - #endif - #endif -#elif defined __NVCOMPILER - #pragma diagnostic pop -#endif - -template <size_t k, class Extents, class OffsetType, class ExtentType, - class StrideType> -MDSPAN_INLINE_FUNCTION -constexpr OffsetType -last_of(std::integral_constant<size_t, k>, const Extents &, - const strided_slice<OffsetType, ExtentType, StrideType> &r) { - return r.extent; -} - -// get stride of slices -template <class T> -MDSPAN_INLINE_FUNCTION -constexpr auto stride_of(const T &) { - return std::integral_constant<size_t, 1>(); -} - -template <class OffsetType, class ExtentType, class StrideType> -MDSPAN_INLINE_FUNCTION -constexpr auto -stride_of(const strided_slice<OffsetType, ExtentType, StrideType> &r) { - return r.stride; -} - -// divide which can deal with integral constant preservation -template <class IndexT, class T0, class T1> -MDSPAN_INLINE_FUNCTION -constexpr auto divide(const T0 &v0, const T1 &v1) { - return IndexT(v0) / IndexT(v1); -} - -template <class IndexT, class T0, T0 v0, class T1, T1 v1> -MDSPAN_INLINE_FUNCTION -constexpr auto divide(const std::integral_constant<T0, v0> &, - const std::integral_constant<T1, v1> &) { - // cutting short division by zero - // this is used for strided_slice with zero extent/stride - return std::integral_constant<IndexT, v0 == 0 ? 0 : v0 / v1>(); -} - -// multiply which can deal with integral constant preservation -template <class IndexT, class T0, class T1> -MDSPAN_INLINE_FUNCTION -constexpr auto multiply(const T0 &v0, const T1 &v1) { - return IndexT(v0) * IndexT(v1); -} - -template <class IndexT, class T0, T0 v0, class T1, T1 v1> -MDSPAN_INLINE_FUNCTION -constexpr auto multiply(const std::integral_constant<T0, v0> &, - const std::integral_constant<T1, v1> &) { - return std::integral_constant<IndexT, v0 * v1>(); -} - -// compute new static extent from range, preserving static knowledge -template <class Arg0, class Arg1> struct StaticExtentFromRange { - constexpr static size_t value = dynamic_extent; -}; - -template <class Integral0, Integral0 val0, class Integral1, Integral1 val1> -struct StaticExtentFromRange<std::integral_constant<Integral0, val0>, - std::integral_constant<Integral1, val1>> { - constexpr static size_t value = val1 - val0; -}; - -// compute new static extent from strided_slice, preserving static -// knowledge -template <class Arg0, class Arg1> struct StaticExtentFromStridedRange { - constexpr static size_t value = dynamic_extent; -}; - -template <class Integral0, Integral0 val0, class Integral1, Integral1 val1> -struct StaticExtentFromStridedRange<std::integral_constant<Integral0, val0>, - std::integral_constant<Integral1, val1>> { - constexpr static size_t value = val0 > 0 ? 1 + (val0 - 1) / val1 : 0; -}; - -// creates new extents through recursive calls to next_extent member function -// next_extent has different overloads for different types of stride specifiers -template <size_t K, class Extents, size_t... NewExtents> -struct extents_constructor { - MDSPAN_TEMPLATE_REQUIRES( - class Slice, class... SlicesAndExtents, - /* requires */(!std::is_convertible_v<Slice, size_t> && - !is_strided_slice<Slice>::value) - ) - MDSPAN_INLINE_FUNCTION - constexpr static auto next_extent(const Extents &ext, const Slice &sl, - SlicesAndExtents... slices_and_extents) { - constexpr size_t new_static_extent = StaticExtentFromRange< - decltype(first_of(std::declval<Slice>())), - decltype(last_of(std::integral_constant<size_t, Extents::rank() - K>(), - std::declval<Extents>(), - std::declval<Slice>()))>::value; - - using next_t = - extents_constructor<K - 1, Extents, NewExtents..., new_static_extent>; - using index_t = typename Extents::index_type; - return next_t::next_extent( - ext, slices_and_extents..., - index_t(last_of(std::integral_constant<size_t, Extents::rank() - K>(), ext, - sl)) - - index_t(first_of(sl))); - } - - MDSPAN_TEMPLATE_REQUIRES( - class Slice, class... SlicesAndExtents, - /* requires */ (std::is_convertible_v<Slice, size_t>) - ) - MDSPAN_INLINE_FUNCTION - constexpr static auto next_extent(const Extents &ext, const Slice &, - SlicesAndExtents... slices_and_extents) { - using next_t = extents_constructor<K - 1, Extents, NewExtents...>; - return next_t::next_extent(ext, slices_and_extents...); - } - - template <class OffsetType, class ExtentType, class StrideType, - class... SlicesAndExtents> - MDSPAN_INLINE_FUNCTION - constexpr static auto - next_extent(const Extents &ext, - const strided_slice<OffsetType, ExtentType, StrideType> &r, - SlicesAndExtents... slices_and_extents) { - using index_t = typename Extents::index_type; - using new_static_extent_t = - StaticExtentFromStridedRange<ExtentType, StrideType>; - if constexpr (new_static_extent_t::value == dynamic_extent) { - using next_t = - extents_constructor<K - 1, Extents, NewExtents..., dynamic_extent>; - return next_t::next_extent( - ext, slices_and_extents..., - r.extent > 0 ? 1 + divide<index_t>(r.extent - 1, r.stride) : 0); - } else { - constexpr size_t new_static_extent = new_static_extent_t::value; - using next_t = - extents_constructor<K - 1, Extents, NewExtents..., new_static_extent>; - return next_t::next_extent( - ext, slices_and_extents..., index_t(divide<index_t>(ExtentType(), StrideType()))); - } - } -}; - -template <class Extents, size_t... NewStaticExtents> -struct extents_constructor<0, Extents, NewStaticExtents...> { - - template <class... NewExtents> - MDSPAN_INLINE_FUNCTION - constexpr static auto next_extent(const Extents &, NewExtents... new_exts) { - return extents<typename Extents::index_type, NewStaticExtents...>( - new_exts...); - } -}; - -} // namespace detail - -// submdspan_extents creates new extents given src extents and submdspan slice -// specifiers -template <class IndexType, size_t... Extents, class... SliceSpecifiers> -MDSPAN_INLINE_FUNCTION -constexpr auto submdspan_extents(const extents<IndexType, Extents...> &src_exts, - SliceSpecifiers... slices) { - - using ext_t = extents<IndexType, Extents...>; - return detail::extents_constructor<ext_t::rank(), ext_t>::next_extent( - src_exts, slices...); -} -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p2630_bits/submdspan_mapping.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p2630_bits/submdspan_mapping.hpp deleted file mode 100644 index cf1bdd1e56f2b1ec356de554fe0cf8685aa76ded..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p2630_bits/submdspan_mapping.hpp +++ /dev/null @@ -1,452 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER - -#pragma once - -#include <array> -#include <tuple> -#include <type_traits> -#include <utility> // index_sequence - -// Suppress spurious warning with NVCC about no return statement. -// This is a known issue in NVCC and NVC++ -// Depending on the CUDA and GCC version we need both the builtin -// and the diagnostic push. I tried really hard to find something shorter -// but no luck ... -#if defined __NVCC__ -#ifdef __NVCC_DIAG_PRAGMA_SUPPORT__ -#pragma nv_diagnostic push -#pragma nv_diag_suppress = implicit_return_from_non_void_function -#else -#ifdef __CUDA_ARCH__ -#pragma diagnostic push -#pragma diag_suppress implicit_return_from_non_void_function -#endif -#endif -#elif defined __NVCOMPILER -#pragma diagnostic push -#pragma diag_suppress = implicit_return_from_non_void_function -#endif - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -//****************************************** -// Return type of submdspan_mapping overloads -//****************************************** -template <class LayoutMapping> struct submdspan_mapping_result { - _MDSPAN_NO_UNIQUE_ADDRESS LayoutMapping mapping{}; - size_t offset; -}; - -namespace detail { -// We use const Slice& and not Slice&& because the various -// submdspan_mapping_impl overloads use their slices arguments -// multiple times. This makes perfect forwarding not useful, but we -// still don't want to pass those (possibly of size 64 x 3 bits) -// objects by value. -template <class IndexType, class Slice> -MDSPAN_INLINE_FUNCTION constexpr bool -one_slice_out_of_bounds(const IndexType &ext, const Slice &slice) { - using common_t = - std::common_type_t<decltype(detail::first_of(slice)), IndexType>; - return static_cast<common_t>(detail::first_of(slice)) == - static_cast<common_t>(ext); -} - -template <size_t... RankIndices, class IndexType, size_t... Exts, - class... Slices> -MDSPAN_INLINE_FUNCTION constexpr bool -any_slice_out_of_bounds_helper(std::index_sequence<RankIndices...>, - const extents<IndexType, Exts...> &exts, - const Slices &... slices) { - return _MDSPAN_FOLD_OR( - (one_slice_out_of_bounds(exts.extent(RankIndices), slices))); -} - -template <class IndexType, size_t... Exts, class... Slices> -MDSPAN_INLINE_FUNCTION constexpr bool -any_slice_out_of_bounds(const extents<IndexType, Exts...> &exts, - const Slices &... slices) { - return any_slice_out_of_bounds_helper( - std::make_index_sequence<sizeof...(Slices)>(), exts, slices...); -} - -// constructs sub strides -template <class SrcMapping, class... slice_strides, size_t... InvMapIdxs> -MDSPAN_INLINE_FUNCTION constexpr auto construct_sub_strides( - const SrcMapping &src_mapping, std::index_sequence<InvMapIdxs...>, - const std::tuple<slice_strides...> &slices_stride_factor) { - using index_type = typename SrcMapping::index_type; - return std::array<typename SrcMapping::index_type, sizeof...(InvMapIdxs)>{ - (static_cast<index_type>(src_mapping.stride(InvMapIdxs)) * - static_cast<index_type>(std::get<InvMapIdxs>(slices_stride_factor)))...}; -} - -template<class SliceSpecifier, class IndexType> -struct is_range_slice { - constexpr static bool value = - std::is_same_v<SliceSpecifier, full_extent_t> || - std::is_convertible_v<SliceSpecifier, - std::tuple<IndexType, IndexType>>; -}; - -template<class SliceSpecifier, class IndexType> -constexpr bool is_range_slice_v = is_range_slice<SliceSpecifier, IndexType>::value; - -template<class SliceSpecifier, class IndexType> -struct is_index_slice { - constexpr static bool value = std::is_convertible_v<SliceSpecifier, IndexType>; -}; - -template<class SliceSpecifier, class IndexType> -constexpr bool is_index_slice_v = is_index_slice<SliceSpecifier, IndexType>::value; - -} // namespace detail - -//********************************** -// layout_left submdspan_mapping -//********************************* -namespace detail { - -// Figure out whether to preserve layout_left -template <class IndexType, size_t SubRank, class IndexSequence, - class... SliceSpecifiers> -struct deduce_layout_left_submapping; - -template <class IndexType, size_t SubRank, size_t... Idx, - class... SliceSpecifiers> -struct deduce_layout_left_submapping< - IndexType, SubRank, std::index_sequence<Idx...>, SliceSpecifiers...> { - - using count_range = index_sequence_scan_impl< - 0, (is_index_slice_v<SliceSpecifiers, IndexType> ? 0 : 1)...>; - - constexpr static int gap_len = - (((Idx > 0 && count_range::get(Idx) == 1 && - is_index_slice_v<SliceSpecifiers, IndexType>) - ? 1 - : 0) + - ... + 0); - - MDSPAN_INLINE_FUNCTION - constexpr static bool layout_left_value() { - // Use layout_left for rank 0 - if constexpr (SubRank == 0) { - return true; - // Use layout_left for rank 1 result if leftmost slice specifier is range like - } else if constexpr (SubRank == 1) { - return ((Idx > 0 || is_range_slice_v<SliceSpecifiers, IndexType>)&&...); - } else { - // Preserve if leftmost SubRank-1 slices are full_extent_t and - // the slice at idx Subrank - 1 is a range and - // for idx > SubRank the slice is an index - return ((((Idx < SubRank - 1) && std::is_same_v<SliceSpecifiers, full_extent_t>) || - ((Idx == SubRank - 1) && is_range_slice_v<SliceSpecifiers, IndexType>) || - ((Idx > SubRank - 1) && is_index_slice_v<SliceSpecifiers, IndexType>)) && ...); - } -#if defined(__NVCC__) && !defined(__CUDA_ARCH__) && defined(__GNUC__) - __builtin_unreachable(); -#endif - } - - MDSPAN_INLINE_FUNCTION - constexpr static bool layout_left_padded_value() { - // Technically could also keep layout_left_padded for SubRank==0 - // and SubRank==1 with leftmost slice specifier being a contiguous range - // but we intercept these cases separately - - // In all other cases: - // leftmost slice must be range - // then there can be a gap with index slices - // then SubRank - 2 full_extent slices - // then another range slice - // then more index slices - // e.g. R I I I F F F R I I for obtaining a rank-5 from a rank-10 - return ((((Idx == 0) && is_range_slice_v<SliceSpecifiers, IndexType>) || - ((Idx > 0 && Idx <= gap_len) && is_index_slice_v<SliceSpecifiers, IndexType>) || - ((Idx > gap_len && Idx < gap_len + SubRank - 1) && std::is_same_v<SliceSpecifiers, full_extent_t>) || - ((Idx == gap_len + SubRank - 1) && is_range_slice_v<SliceSpecifiers, IndexType>) || - ((Idx > gap_len + SubRank - 1) && is_index_slice_v<SliceSpecifiers, IndexType>)) && ... ); - } -}; - -} // namespace detail - -// Actual submdspan mapping call -template <class Extents> -template <class... SliceSpecifiers> -MDSPAN_INLINE_FUNCTION constexpr auto -layout_left::mapping<Extents>::submdspan_mapping_impl( - SliceSpecifiers... slices) const { - - // compute sub extents - using src_ext_t = Extents; - auto dst_ext = submdspan_extents(extents(), slices...); - using dst_ext_t = decltype(dst_ext); - - // figure out sub layout type - using deduce_layout = detail::deduce_layout_left_submapping< - typename dst_ext_t::index_type, dst_ext_t::rank(), - std::make_index_sequence<src_ext_t::rank()>, - SliceSpecifiers...>; - - using dst_layout_t = std::conditional_t< - deduce_layout::layout_left_value(), layout_left, - std::conditional_t< - deduce_layout::layout_left_padded_value(), - MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_left_padded<dynamic_extent>, - layout_stride>>; - using dst_mapping_t = typename dst_layout_t::template mapping<dst_ext_t>; - - // Figure out if any slice's lower bound equals the corresponding extent. - // If so, bypass evaluating the layout mapping. This fixes LWG Issue 4060. - const bool out_of_bounds = - detail::any_slice_out_of_bounds(this->extents(), slices...); - auto offset = static_cast<size_t>( - out_of_bounds ? this->required_span_size() - : this->operator()(detail::first_of(slices)...)); - - if constexpr (std::is_same_v<dst_layout_t, layout_left>) { - // layout_left case - return submdspan_mapping_result<dst_mapping_t>{dst_mapping_t(dst_ext), - offset}; - } else if constexpr (std::is_same_v<dst_layout_t, - MDSPAN_IMPL_PROPOSED_NAMESPACE:: - layout_left_padded<dynamic_extent>>) { - return submdspan_mapping_result<dst_mapping_t>{ - dst_mapping_t(dst_ext, stride(1 + deduce_layout::gap_len)), offset}; - } else { - // layout_stride case - auto inv_map = detail::inv_map_rank(std::integral_constant<size_t, 0>(), - std::index_sequence<>(), slices...); - return submdspan_mapping_result<dst_mapping_t> { - dst_mapping_t(dst_ext, - detail::construct_sub_strides( - *this, inv_map, -// HIP needs deduction guides to have markups so we need to be explicit -// NVCC 11.0 has a bug with deduction guide here, tested that 11.2 does not have -// the issue But Clang-CUDA also doesn't accept the use of deduction guide so -// disable it for CUDA altogether -#if defined(_MDSPAN_HAS_HIP) || defined(_MDSPAN_HAS_CUDA) - std::tuple<decltype(detail::stride_of(slices))...>{ - detail::stride_of(slices)...})), -#else - std::tuple{detail::stride_of(slices)...})), -#endif - offset - }; - } -#if defined(__NVCC__) && !defined(__CUDA_ARCH__) && defined(__GNUC__) - __builtin_unreachable(); -#endif -} - -//********************************** -// layout_right submdspan_mapping -//********************************* -namespace detail { - -// Figure out whether to preserve layout_right -template <class IndexType, size_t SubRank, class IndexSequence, - class... SliceSpecifiers> -struct deduce_layout_right_submapping; - -template <class IndexType, size_t SubRank, size_t... Idx, - class... SliceSpecifiers> -struct deduce_layout_right_submapping< - IndexType, SubRank, std::index_sequence<Idx...>, SliceSpecifiers...> { - - static constexpr size_t Rank = sizeof...(Idx); - using count_range = index_sequence_scan_impl< - 0, (std::is_convertible_v<SliceSpecifiers, IndexType> ? 0 : 1)...>; - //__static_partial_sums<!std::is_convertible_v<SliceSpecifiers, - // IndexType>...>; - constexpr static int gap_len = - (((Idx < Rank - 1 && count_range::get(Idx) == SubRank - 1 && - std::is_convertible_v<SliceSpecifiers, IndexType>) - ? 1 - : 0) + - ... + 0); - - MDSPAN_INLINE_FUNCTION - constexpr static bool layout_right_value() { - // Use layout_right for rank 0 - if constexpr (SubRank == 0) { - return true; - // Use layout_right for rank 1 result if rightmost slice specifier is range like - } else if constexpr (SubRank == 1) { - return ((Idx < Rank - 1 || is_range_slice_v<SliceSpecifiers, IndexType>)&&...); - } else { - // Preserve if rightmost SubRank-1 slices are full_extent_t and - // the slice at idx Rank-Subrank is a range and - // for idx < Rank - SubRank the slice is an index - return ((((Idx >= Rank - SubRank) && std::is_same_v<SliceSpecifiers, full_extent_t>) || - ((Idx == Rank - SubRank) && is_range_slice_v<SliceSpecifiers, IndexType>) || - ((Idx < Rank - SubRank) && is_index_slice_v<SliceSpecifiers, IndexType>)) && ...); - } -#if defined(__NVCC__) && !defined(__CUDA_ARCH__) && defined(__GNUC__) - __builtin_unreachable(); -#endif - } - - MDSPAN_INLINE_FUNCTION - constexpr static bool layout_right_padded_value() { - // Technically could also keep layout_right_padded for SubRank==0 - // and SubRank==1 with rightmost slice specifier being a contiguous range - // but we intercept these cases separately - - // In all other cases: - // rightmost slice must be range - // then there can be a gap with index slices - // then SubRank - 2 full_extent slices - // then another range slice - // then more index slices - // e.g. I I R F F F I I I R for obtaining a rank-5 from a rank-10 - return ((((Idx == Rank - 1) && is_range_slice_v<SliceSpecifiers, IndexType>) || - ((Idx >= Rank - gap_len - 1 && Idx < Rank - 1) && is_index_slice_v<SliceSpecifiers, IndexType>) || - ((Idx > Rank - gap_len - SubRank && Idx < Rank - gap_len - 1) && std::is_same_v<SliceSpecifiers, full_extent_t>) || - ((Idx == Rank - gap_len - SubRank) && is_range_slice_v<SliceSpecifiers, IndexType>) || - ((Idx < Rank - gap_len - SubRank) && is_index_slice_v<SliceSpecifiers, IndexType>)) && ... ); - } -}; - -} // namespace detail - -// Actual submdspan mapping call -template <class Extents> -template <class... SliceSpecifiers> -MDSPAN_INLINE_FUNCTION constexpr auto -layout_right::mapping<Extents>::submdspan_mapping_impl( - SliceSpecifiers... slices) const { - - // compute sub extents - using src_ext_t = Extents; - auto dst_ext = submdspan_extents(extents(), slices...); - using dst_ext_t = decltype(dst_ext); - - // figure out sub layout type - using deduce_layout = detail::deduce_layout_right_submapping< - typename dst_ext_t::index_type, dst_ext_t::rank(), - std::make_index_sequence<src_ext_t::rank()>, - SliceSpecifiers...>; - - using dst_layout_t = std::conditional_t< - deduce_layout::layout_right_value(), layout_right, - std::conditional_t< - deduce_layout::layout_right_padded_value(), - MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_right_padded<dynamic_extent>, - layout_stride>>; - using dst_mapping_t = typename dst_layout_t::template mapping<dst_ext_t>; - - // Figure out if any slice's lower bound equals the corresponding extent. - // If so, bypass evaluating the layout mapping. This fixes LWG Issue 4060. - const bool out_of_bounds = - detail::any_slice_out_of_bounds(this->extents(), slices...); - auto offset = static_cast<size_t>( - out_of_bounds ? this->required_span_size() - : this->operator()(detail::first_of(slices)...)); - - if constexpr (std::is_same_v<dst_layout_t, layout_right>) { - // layout_right case - return submdspan_mapping_result<dst_mapping_t>{dst_mapping_t(dst_ext), - offset}; - } else if constexpr (std::is_same_v< - dst_layout_t, - MDSPAN_IMPL_PROPOSED_NAMESPACE::layout_right_padded< - dynamic_extent>>) { - return submdspan_mapping_result<dst_mapping_t>{ - dst_mapping_t(dst_ext, - stride(src_ext_t::rank() - 2 - deduce_layout::gap_len)), - offset}; - } else { - // layout_stride case - auto inv_map = detail::inv_map_rank(std::integral_constant<size_t, 0>(), - std::index_sequence<>(), slices...); - return submdspan_mapping_result<dst_mapping_t> { - dst_mapping_t(dst_ext, - detail::construct_sub_strides( - *this, inv_map, -// HIP needs deduction guides to have markups so we need to be explicit -// NVCC 11.0 has a bug with deduction guide here, tested that 11.2 does not have -// the issue But Clang-CUDA also doesn't accept the use of deduction guide so -// disable it for CUDA altogether -#if defined(_MDSPAN_HAS_HIP) || defined(_MDSPAN_HAS_CUDA) - std::tuple<decltype(detail::stride_of(slices))...>{ - detail::stride_of(slices)...})), -#else - std::tuple{detail::stride_of(slices)...})), -#endif - offset - }; - } -#if defined(__NVCC__) && !defined(__CUDA_ARCH__) && defined(__GNUC__) - __builtin_unreachable(); -#endif -} - -//********************************** -// layout_stride submdspan_mapping -//********************************* -template <class Extents> -template <class... SliceSpecifiers> -MDSPAN_INLINE_FUNCTION constexpr auto -layout_stride::mapping<Extents>::submdspan_mapping_impl( - SliceSpecifiers... slices) const { - auto dst_ext = submdspan_extents(extents(), slices...); - using dst_ext_t = decltype(dst_ext); - auto inv_map = detail::inv_map_rank(std::integral_constant<size_t, 0>(), - std::index_sequence<>(), slices...); - using dst_mapping_t = typename layout_stride::template mapping<dst_ext_t>; - - // Figure out if any slice's lower bound equals the corresponding extent. - // If so, bypass evaluating the layout mapping. This fixes LWG Issue 4060. - const bool out_of_bounds = - detail::any_slice_out_of_bounds(this->extents(), slices...); - auto offset = static_cast<size_t>( - out_of_bounds ? this->required_span_size() - : this->operator()(detail::first_of(slices)...)); - - return submdspan_mapping_result<dst_mapping_t> { - dst_mapping_t(dst_ext, - detail::construct_sub_strides( - *this, inv_map, -// HIP needs deduction guides to have markups so we need to be explicit -// NVCC 11.0 has a bug with deduction guide here, tested that 11.2 does not have -// the issue -#if defined(_MDSPAN_HAS_HIP) || \ - (defined(__NVCC__) && \ - (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__ * 10) < 1120) - std::tuple<decltype(detail::stride_of(slices))...>( - detail::stride_of(slices)...))), -#else - std::tuple(detail::stride_of(slices)...))), -#endif - offset - }; -} - -} // namespace MDSPAN_IMPL_STANDARD_NAMESPACE - -#if defined __NVCC__ -#ifdef __NVCC_DIAG_PRAGMA_SUPPORT__ -#pragma nv_diagnostic pop -#else -#ifdef __CUDA_ARCH__ -#pragma diagnostic pop -#endif -#endif -#elif defined __NVCOMPILER -#pragma diagnostic pop -#endif diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p2642_bits/layout_padded.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p2642_bits/layout_padded.hpp deleted file mode 100644 index 99e24fa450ae7973c3ad44e314bbefbc5d82185a..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p2642_bits/layout_padded.hpp +++ /dev/null @@ -1,852 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER -#pragma once - -#include <cassert> -#include "layout_padded_fwd.hpp" -#include "../__p0009_bits/dynamic_extent.hpp" -#include "../__p0009_bits/extents.hpp" -#include "../__p0009_bits/mdspan.hpp" -#include "../__p0009_bits/layout_left.hpp" -#include "../__p0009_bits/layout_right.hpp" -#include "../__p0009_bits/layout_stride.hpp" - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -namespace MDSPAN_IMPL_PROPOSED_NAMESPACE { - -namespace detail { -template<class _T> -MDSPAN_INLINE_FUNCTION -constexpr _T -find_next_multiple(_T alignment, _T offset) -{ - if ( alignment == 0 ) { - return _T(0); - } else { - return ( ( offset + alignment - 1 ) / alignment) * alignment; - } -} - -template <class _ExtentsType, size_t _PaddingValue, size_t _ExtentToPadIdx> -MDSPAN_INLINE_FUNCTION constexpr size_t get_actual_static_padding_value() { - constexpr auto rank = _ExtentsType::rank(); - - if constexpr (rank <= typename _ExtentsType::rank_type(1)) { - return 0; - } else if constexpr (_PaddingValue != dynamic_extent && - _ExtentsType::static_extent(_ExtentToPadIdx) != - dynamic_extent) { - static_assert( - (_PaddingValue != 0) || - (_ExtentsType::static_extent(_ExtentToPadIdx) == 0), - "padding stride can be 0 only if " - "extents_type::static_extent(extent-to-pad) is 0 or dynamic_extent"); - return find_next_multiple(_PaddingValue, - _ExtentsType::static_extent(_ExtentToPadIdx)); - } else { - return dynamic_extent; - } - // Missing return statement warning from NVCC -#ifdef __NVCC__ - return 0; -#endif -} - -template <size_t _PaddingValue, typename _Extents, size_t _ExtentToPadIdx, size_t _Rank, typename Enabled = void> -struct static_array_type_for_padded_extent -{ - static constexpr size_t padding_value = _PaddingValue; - using index_type = typename _Extents::index_type; - using extents_type = _Extents; - using type = ::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::maybe_static_array< - index_type, size_t, dynamic_extent, - detail::get_actual_static_padding_value<extents_type, padding_value, - _ExtentToPadIdx>()>; -}; - -template <size_t _PaddingValue, typename _Extents, size_t _ExtentToPadIdx, size_t Rank> -struct static_array_type_for_padded_extent<_PaddingValue, _Extents, - _ExtentToPadIdx, Rank, std::enable_if_t<Rank <= 1>> { - using index_type = typename _Extents::index_type; - using extents_type = _Extents; - using type = - ::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::maybe_static_array< - index_type, size_t, dynamic_extent, 0>; -}; - -template <size_t _PaddingValue, typename _Extents, size_t _ExtentToPadIdx> -struct padded_extent { - static constexpr size_t padding_value = _PaddingValue; - using index_type = typename _Extents::index_type; - using extents_type = _Extents; - using static_array_type = typename static_array_type_for_padded_extent< - padding_value, _Extents, _ExtentToPadIdx, _Extents::rank()>::type; - - static constexpr auto static_value() { return static_array_type::static_value(0); } - - MDSPAN_INLINE_FUNCTION - static constexpr static_array_type - init_padding(const _Extents &exts) { - if constexpr ((_Extents::rank() > 1) && (padding_value == dynamic_extent)) { - return {exts.extent(_ExtentToPadIdx)}; - } else { - return init_padding(exts, padding_value); - } - // Missing return statement warning from NVCC -#ifdef __NVCC__ - return {}; -#endif - } - - MDSPAN_INLINE_FUNCTION static constexpr static_array_type - init_padding([[maybe_unused]] const _Extents &exts, - [[maybe_unused]] index_type pv) { - if constexpr (_Extents::rank() > 1) { - return {find_next_multiple(pv, - exts.extent(_ExtentToPadIdx))}; - } else { - return {}; - } - // Missing return statement warning from NVCC -#ifdef __NVCC__ - return {}; -#endif - } - - template <typename _Mapping, size_t _PaddingStrideIdx> - MDSPAN_INLINE_FUNCTION static constexpr static_array_type - init_padding([[maybe_unused]] const _Mapping &other_mapping, - std::integral_constant<size_t, _PaddingStrideIdx>) { - if constexpr (_Extents::rank() > 1) { - return {other_mapping.stride(_PaddingStrideIdx)}; - } else { - return {}; - } - // Missing return statement warning from NVCC -#ifdef __NVCC__ - return {}; -#endif - } -}; -} // namespace detail - -template <size_t PaddingValue> -template <class Extents> -class layout_left_padded<PaddingValue>::mapping { -public: - static constexpr size_t padding_value = PaddingValue; - - using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_left_padded<padding_value>; - -#ifndef MDSPAN_INTERNAL_TEST -private: -#endif // MDSPAN_INTERNAL_TEST - - static constexpr rank_type padded_stride_idx = detail::layout_padded_constants<layout_type, extents_type>::padded_stride_idx; - static constexpr rank_type extent_to_pad_idx = detail::layout_padded_constants<layout_type, extents_type>::extent_to_pad_idx; - - static_assert((padding_value != 0) - || (extents_type::static_extent(extent_to_pad_idx) == 0) - || (extents_type::static_extent(extent_to_pad_idx) == dynamic_extent), - "out of bounds access for rank 0"); - - using padded_stride_type = detail::padded_extent< padding_value, extents_type, extent_to_pad_idx >; - - static constexpr size_t static_padding_stride = padded_stride_type::static_value(); - - typename padded_stride_type::static_array_type padded_stride = {}; - extents_type exts = {}; - - MDSPAN_INLINE_FUNCTION constexpr index_type - compute_offset(std::index_sequence<>) const { - return 0; - } - - template <size_t Rank, class IndexOffset> - MDSPAN_INLINE_FUNCTION constexpr index_type - compute_offset(std::index_sequence<Rank>, IndexOffset index_offset) const { - return index_offset; - } - - template <size_t... Ranks, class... IndexOffsets> - MDSPAN_INLINE_FUNCTION constexpr index_type - compute_offset(std::index_sequence<Ranks...>, - IndexOffsets... index_offsets) const { - index_type indices[] = {static_cast<index_type>(index_offsets)...}; - // self-recursive fold trick from - // https://github.com/llvm/llvm-project/blob/96e1914aa2e6d8966acbfbe2f4d184201f1aa318/libcxx/include/mdspan/layout_left.h#L144 - index_type res = 0; - ((res = indices[extents_type::rank() - 1 - Ranks] + - ((extents_type::rank() - 1 - Ranks) == extent_to_pad_idx - ? padded_stride.value(0) - : exts.extent(extents_type::rank() - 1 - Ranks)) * - res), - ...); - return res; - } - -public: -#if !MDSPAN_HAS_CXX_20 - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr mapping() - : mapping(extents_type{}) - {} -#else - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr mapping() - requires(static_padding_stride != dynamic_extent) = default; - - MDSPAN_INLINE_FUNCTION - constexpr mapping() - requires(static_padding_stride == dynamic_extent) - : mapping(extents_type{}) - {} -#endif - - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(const mapping&) noexcept = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED mapping& operator=(const mapping&) noexcept = default; - - /** - * Initializes the mapping with the given extents. - * - * \param ext the given extents - */ - MDSPAN_INLINE_FUNCTION - constexpr mapping(const extents_type& ext) - : padded_stride(padded_stride_type::init_padding(ext)), exts(ext) - {} - - /** - * Initializes the mapping with the given extents and the specified padding value. - * - * This overload participates in overload resolution only if `is_convertible_v<Size, index_type>` - * is `true` and `is_nothrow_constructible_v<index_type, Size>` is `true` - * - * \param ext the given extents - * \param padding_value the padding value - */ - MDSPAN_TEMPLATE_REQUIRES( - class _Size, - /* requires */ ( - std::is_convertible_v<_Size, index_type> - && std::is_nothrow_constructible_v<index_type, _Size> - ) - ) - MDSPAN_INLINE_FUNCTION - constexpr mapping(const extents_type &ext, _Size dynamic_padding_value) - : padded_stride(padded_stride_type::init_padding(ext, dynamic_padding_value)), exts(ext) - { - assert((padding_value == dynamic_extent) || (static_cast<index_type>(padding_value) == static_cast<index_type>(dynamic_padding_value))); - } - - /** - * Converting constructor from `layout_left::mapping`. - * - * This overload participates in overload resolution only if - * `is_constructible_v<extents_type, OtherExtents>` is true. If - * `OtherExtents::rank() > 1` then one of `padding_value`, `static_extent(0)`, - * or `OtherExtents::static_extent(0)` must be `dynamic_extent`; otherwise, - * `OtherExtents::static_extent(0)` must be equal to the least multiple of - * `padding_value` greater than or equal to `extents_type::static_extent(0)` - */ - MDSPAN_TEMPLATE_REQUIRES( - class _OtherExtents, - /* requires */ (std::is_constructible_v<extents_type, _OtherExtents>)) - MDSPAN_CONDITIONAL_EXPLICIT( - (!std::is_convertible_v<_OtherExtents, extents_type>)) - MDSPAN_INLINE_FUNCTION - constexpr mapping(const layout_left::mapping<_OtherExtents> &other_mapping) - : padded_stride(padded_stride_type::init_padding( - other_mapping, - std::integral_constant<size_t, padded_stride_idx>{})), - exts(other_mapping.extents()) { - static_assert( - (_OtherExtents::rank() > 1) || - (static_padding_stride != dynamic_extent) || - (_OtherExtents::static_extent(extent_to_pad_idx) != dynamic_extent) || - (static_padding_stride == - _OtherExtents::static_extent(extent_to_pad_idx))); - } - - /** - * Converting constructor from `layout_stride::mapping`. - * - * This overload participates in overload resolution only if - * `is_constructible_v<extents_type, OtherExtents>` is true - */ - MDSPAN_TEMPLATE_REQUIRES( - class _OtherExtents, - /* requires */ (std::is_constructible_v<extents_type, _OtherExtents>)) - MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 0)) - MDSPAN_INLINE_FUNCTION - constexpr mapping(const layout_stride::mapping<_OtherExtents> &other_mapping) - : padded_stride(padded_stride_type::init_padding( - other_mapping, - std::integral_constant<size_t, padded_stride_idx>{})), - exts(other_mapping.extents()) {} - - /** - * Converting constructor from `layout_left_padded::mapping`. - * - * This overload participates in overload resolution only if - * `is_constructible_v<extents_type, OtherExtents>` is true. Either - * `padding_value` or `OtherPaddingStride` must be `std::dynamic_extent`, or - * `padding_value == OtherPaddingStride`. - */ - MDSPAN_TEMPLATE_REQUIRES( - class _Mapping, - /* requires */ (detail::is_layout_left_padded_mapping<_Mapping>::value - &&std::is_constructible_v< - extents_type, typename _Mapping::extents_type>)) - MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 1 && - (padding_value == dynamic_extent || - _Mapping::padding_value == dynamic_extent))) - MDSPAN_INLINE_FUNCTION - constexpr mapping(const _Mapping &other_mapping) - : padded_stride(padded_stride_type::init_padding( - other_mapping, - std::integral_constant<size_t, padded_stride_idx>{})), - exts(other_mapping.extents()) { - static_assert(padding_value == dynamic_extent || - _Mapping::padding_value == dynamic_extent || - padding_value == _Mapping::padding_value); - } - - /** - * Converting constructor from `layout_right_padded::mapping`. - * - * This overload participates in overload resolution only if - * `extents_type::rank()` is 0 or 1 and `is_constructible_v<extents_type, - * OtherExtents>` is `true`. - */ - MDSPAN_TEMPLATE_REQUIRES( - class _Mapping, - /* requires */ (detail::is_layout_right_padded_mapping<_Mapping>::value - &&extents_type::rank() <= 1 && - std::is_constructible_v<extents_type, - typename _Mapping::extents_type>)) - MDSPAN_CONDITIONAL_EXPLICIT( - (!std::is_convertible_v<typename _Mapping::extents_type, extents_type>)) - MDSPAN_INLINE_FUNCTION - constexpr mapping(const _Mapping &other_mapping) noexcept - : padded_stride(padded_stride_type::init_padding( - other_mapping.extents(), - other_mapping.extents().extent(extent_to_pad_idx))), - exts(other_mapping.extents()) {} - - MDSPAN_INLINE_FUNCTION constexpr const extents_type & - extents() const noexcept { - return exts; - } - - MDSPAN_INLINE_FUNCTION constexpr std::array<index_type, extents_type::rank()> - strides() const noexcept { - if constexpr (extents_type::rank() == 0) { - return {}; - } else if constexpr (extents_type::rank() == 1) { - return {1}; - } else { - index_type value = 1; - std::array<index_type, extents_type::rank()> s{}; - s[extent_to_pad_idx] = value; - value *= padded_stride.value(0); - for (rank_type r = extent_to_pad_idx + 1; r < extents_type::rank() - 1; - ++r) { - s[r] = value; - value *= exts.extent(r); - } - s[extents_type::rank() - 1] = value; - return s; - } - } - - MDSPAN_INLINE_FUNCTION constexpr index_type - required_span_size() const noexcept { - if constexpr (extents_type::rank() == 0) { - return 1; - } else if constexpr (extents_type::rank() == 1) { - return exts.extent(0); - } else { - index_type value = padded_stride.value(0); - for (rank_type r = 1; r < extents_type::rank(); ++r) { - value *= exts.extent(r); - } - return value; - } - } - - /** - * Return the mapping given the provided indices per rank. - * - * This overload participates in overload resolution only if: - * - `sizeof...(Indices) == extents_type::rank()`, - * - `(is_convertible_v<Indices, index_type> && ...) is true`, and - * - (is_nothrow_constructible_v<index_type, Indices> && ...) is true. - */ - MDSPAN_TEMPLATE_REQUIRES( - class... _Indices, - /* requires */ (sizeof...(_Indices) == extents_type::rank() && - (::MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: - are_valid_indices<index_type, _Indices...>()))) - MDSPAN_INLINE_FUNCTION constexpr size_t - operator()(_Indices... idxs) const noexcept { -#if !defined(NDEBUG) - ::MDSPAN_IMPL_STANDARD_NAMESPACE::detail::check_all_indices(this->extents(), - idxs...); -#endif // ! NDEBUG - return compute_offset(std::index_sequence_for<_Indices...>{}, idxs...); - } - - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { - return true; - } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { - return (extents_type::rank() <= rank_type(1)) || - (extents_type::static_extent(extent_to_pad_idx) != dynamic_extent && - extents_type::static_extent(extent_to_pad_idx) == - padded_stride_type::static_value()); - } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { - return true; - } - - MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { - return true; - } - MDSPAN_INLINE_FUNCTION constexpr bool is_exhaustive() const noexcept { - return (extents_type::rank() < 2) || - (exts.extent(extent_to_pad_idx) == padded_stride.value(0)); - } - MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { - return true; - } - - MDSPAN_INLINE_FUNCTION - constexpr index_type stride(rank_type r) const noexcept { - assert(r < extents_type::rank()); - if (r == 0) - return index_type(1); - - index_type value = padded_stride.value(0); - for (rank_type k = 1; k < r; k++) - value *= exts.extent(k); - - return value; - } - - /** - * Equality operator between `layout_left_padded`s - * - * This overload only participates in overload resolution if - * `OtherExtents::rank() == extents_type::rank()`. - * - * \note There is currently a difference from p2642r2, where this function is - * specified as taking `layout_left_padded< padding_value >::mapping< - * Extents>`. However, this makes `padding_value` non-deducible. - */ - MDSPAN_TEMPLATE_REQUIRES( - class _Mapping, - /* requires */ (detail::is_layout_left_padded_mapping<_Mapping>::value && - (_Mapping::extents_type::rank() == extents_type::rank()))) - MDSPAN_INLINE_FUNCTION friend constexpr bool - operator==(const mapping &left, const _Mapping &right) noexcept { - // Workaround for some compilers not short-circuiting properly with - // compile-time checks i.e. we can't access stride(_padding_stride_idx) of a - // rank 0 mapping - bool strides_equal = true; - if constexpr (extents_type::rank() > rank_type(1)) { - strides_equal = - left.stride(padded_stride_idx) == right.stride(padded_stride_idx); - } - return (left.extents() == right.extents()) && strides_equal; - } - -#if !MDSPAN_HAS_CXX_20 - /** - * Inequality operator between `layout_left_padded`s - * - * This overload only participates in overload resolution if - * `OtherExtents::rank() == extents_type::rank()`. - */ - MDSPAN_TEMPLATE_REQUIRES( - class _Mapping, - /* requires */ (detail::is_layout_left_padded_mapping<_Mapping>::value && - (_Mapping::extents_type::rank() == extents_type::rank()))) - MDSPAN_INLINE_FUNCTION friend constexpr bool - operator!=(const mapping &left, const _Mapping &right) noexcept { - return !(left == right); - } -#endif - - // [mdspan.submdspan.mapping], submdspan mapping specialization - template<class... SliceSpecifiers> - constexpr auto submdspan_mapping_impl( - SliceSpecifiers... slices) const; - - template<class... SliceSpecifiers> - friend constexpr auto submdspan_mapping( - const mapping& src, SliceSpecifiers... slices) { - return src.submdspan_mapping_impl(slices...); - } -}; - -template <size_t PaddingValue> -template <class Extents> -class layout_right_padded<PaddingValue>::mapping { -public: - static constexpr size_t padding_value = PaddingValue; - - using extents_type = Extents; - using index_type = typename extents_type::index_type; - using size_type = typename extents_type::size_type; - using rank_type = typename extents_type::rank_type; - using layout_type = layout_right_padded<padding_value>; - -#ifndef MDSPAN_INTERNAL_TEST - private: -#endif // MDSPAN_INTERNAL_TEST - - static constexpr rank_type padded_stride_idx = detail::layout_padded_constants<layout_type, extents_type>::padded_stride_idx; - static constexpr rank_type extent_to_pad_idx = detail::layout_padded_constants<layout_type, extents_type>::extent_to_pad_idx; - - static_assert((padding_value != 0) - || (extents_type::static_extent(extent_to_pad_idx) == 0) - || (extents_type::static_extent(extent_to_pad_idx) == dynamic_extent), - "if padding stride is 0, static_extent(extent-to-pad-rank) must also be 0 or dynamic_extent"); - - using padded_stride_type = detail::padded_extent< padding_value, extents_type, extent_to_pad_idx >; - static constexpr size_t static_padding_stride = padded_stride_type::static_value(); - - typename padded_stride_type::static_array_type padded_stride = {}; - extents_type exts = {}; - - MDSPAN_INLINE_FUNCTION constexpr index_type - compute_offset(std::index_sequence<>) const { - return 0; - } - - template <size_t Rank, class IndexOffset> - MDSPAN_INLINE_FUNCTION constexpr index_type - compute_offset(std::index_sequence<Rank>, IndexOffset index_offset) const { - return index_offset; - } - - template <size_t... Ranks, class... IndexOffsets> - MDSPAN_INLINE_FUNCTION constexpr index_type - compute_offset(std::index_sequence<Ranks...>, - IndexOffsets... index_offsets) const { - // self-recursive fold trick from - // https://github.com/llvm/llvm-project/blob/4d9771741d40cc9cfcccb6b033f43689d36b705a/libcxx/include/mdspan/layout_right.h#L141 - index_type res = 0; - ((res = static_cast<index_type>(index_offsets) + - (Ranks == extent_to_pad_idx ? padded_stride.value(0) - : exts.extent(Ranks)) * - res), - ...); - return res; - } - -public: -#if !MDSPAN_HAS_CXX_20 - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr mapping() - : mapping(extents_type{}) - {} -#else - MDSPAN_INLINE_FUNCTION_DEFAULTED - constexpr mapping() - requires(static_padding_stride != dynamic_extent) = default; - - MDSPAN_INLINE_FUNCTION - constexpr mapping() - requires(static_padding_stride == dynamic_extent) - : mapping(extents_type{}) - {} -#endif - - MDSPAN_INLINE_FUNCTION_DEFAULTED constexpr mapping(const mapping&) noexcept = default; - MDSPAN_INLINE_FUNCTION_DEFAULTED mapping& operator=(const mapping&) noexcept = default; - - /** - * Initializes the mapping with the given extents. - * - * \param ext the given extents - */ - MDSPAN_INLINE_FUNCTION - constexpr mapping(const extents_type &ext) - : padded_stride(padded_stride_type::init_padding(ext)), exts(ext) {} - - /** - * Initializes the mapping with the given extents and the specified padding value. - * - * This overload participates in overload resolution only if `is_convertible_v<Size, index_type>` - * is `true` and `is_nothrow_constructible_v<index_type, Size>` is `true` - * - * \param ext the given extents - * \param padding_value the padding value - */ - MDSPAN_TEMPLATE_REQUIRES( - class _Size, - /* requires */ ( - std::is_convertible_v<_Size, index_type> - && std::is_nothrow_constructible_v<index_type, _Size> - ) - ) - MDSPAN_INLINE_FUNCTION - constexpr mapping(const extents_type &ext, _Size dynamic_padding_value) - : padded_stride(padded_stride_type::init_padding(ext, static_cast<index_type>(dynamic_padding_value))), - exts(ext) { - assert((padding_value == dynamic_extent) || - (static_cast<index_type>(padding_value) == static_cast<index_type>(dynamic_padding_value))); - } - - /** - * Converting constructor from `layout_right::mapping`. - * - * This overload participates in overload resolution only if `is_constructible_v<extents_type, OtherExtents>` is true. - * If `OtherExtents::rank() > 1` then one of `padding_value`, `static_extent(0)`, or `OtherExtents::static_extent(0)` must be `dynamic_extent`; - * otherwise, `OtherExtents::static_extent(0)` must be equal to the least multiple of `padding_value` greater than or equal to `extents_type::static_extent(0)` - */ - MDSPAN_TEMPLATE_REQUIRES( - class _OtherExtents, - /* requires */ (std::is_constructible_v<extents_type, _OtherExtents>)) - MDSPAN_CONDITIONAL_EXPLICIT( - (!std::is_convertible_v<_OtherExtents, extents_type>)) - MDSPAN_INLINE_FUNCTION - constexpr mapping(const layout_right::mapping<_OtherExtents> &other_mapping) - : padded_stride(padded_stride_type::init_padding( - other_mapping, - std::integral_constant<size_t, padded_stride_idx>{})), - exts(other_mapping.extents()) { - static_assert( - (_OtherExtents::rank() > 1) || - (padded_stride_type::static_value() != dynamic_extent) || - (_OtherExtents::static_extent(extent_to_pad_idx) != dynamic_extent) || - (padded_stride_type::static_value() == - _OtherExtents::static_extent(extent_to_pad_idx))); - } - - /** - * Converting constructor from `layout_stride::mapping`. - * - * This overload participates in overload resolution only if - * `is_constructible_v<extents_type, OtherExtents>` is true - */ - MDSPAN_TEMPLATE_REQUIRES( - class _OtherExtents, - /* requires */ (std::is_constructible_v<extents_type, _OtherExtents>)) - MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 0)) - MDSPAN_INLINE_FUNCTION - constexpr mapping(const layout_stride::mapping<_OtherExtents> &other_mapping) - : padded_stride(padded_stride_type::init_padding( - other_mapping, - std::integral_constant<size_t, padded_stride_idx>{})), - exts(other_mapping.extents()) {} - - /** - * Converting constructor from `layout_right_padded::mapping`. - * - * This overload participates in overload resolution only if - * `is_constructible_v<extents_type, OtherExtents>` is true. Either - * `padding_value` or `OtherPaddingStride` must be `std::dynamic_extent`, or - * `padding_value == OtherPaddingStride`. - */ - MDSPAN_TEMPLATE_REQUIRES( - class _Mapping, - /* requires */ (detail::is_layout_right_padded_mapping<_Mapping>::value - &&std::is_constructible_v< - extents_type, typename _Mapping::extents_type>)) - MDSPAN_CONDITIONAL_EXPLICIT((extents_type::rank() > 1 && - (padding_value == dynamic_extent || - _Mapping::padding_value == dynamic_extent))) - MDSPAN_INLINE_FUNCTION - constexpr mapping(const _Mapping &other_mapping) - : padded_stride(padded_stride_type::init_padding( - other_mapping, - std::integral_constant<size_t, padded_stride_idx>{})), - exts(other_mapping.extents()) { - static_assert(padding_value == dynamic_extent || - _Mapping::padding_value == dynamic_extent || - padding_value == _Mapping::padding_value); - } - - /** - * Converting constructor from `layout_left_padded::mapping`. - * - * This overload participates in overload resolution only if - * `extents_type::rank()` is 0 or 1 and `is_constructible_v<extents_type, - * OtherExtents>` is `true`. - */ - MDSPAN_TEMPLATE_REQUIRES( - class _Mapping, - /* requires */ (detail::is_layout_left_padded_mapping<_Mapping>::value - &&extents_type::rank() <= 1 && - std::is_constructible_v<extents_type, - typename _Mapping::extents_type>)) - MDSPAN_CONDITIONAL_EXPLICIT( - (!std::is_convertible_v<typename _Mapping::extents_type, extents_type>)) - MDSPAN_INLINE_FUNCTION - constexpr mapping(const _Mapping &other_mapping) noexcept - : padded_stride(padded_stride_type::init_padding( - other_mapping.extents(), - other_mapping.extents().extent(extent_to_pad_idx))), - exts(other_mapping.extents()) {} - - MDSPAN_INLINE_FUNCTION constexpr const extents_type & - extents() const noexcept { - return exts; - } - - MDSPAN_INLINE_FUNCTION constexpr std::array<index_type, extents_type::rank()> - strides() const noexcept { - if constexpr (extents_type::rank() == 0) { - return {}; - } else if constexpr (extents_type::rank() == 1) { - return {1}; - } else { - index_type value = 1; - std::array<index_type, extents_type::rank()> s{}; - s[extent_to_pad_idx] = value; - value *= padded_stride.value(0); - for (rank_type r = extent_to_pad_idx - 1; r > 0; --r) { - s[r] = value; - value *= exts.extent(r); - } - s[0] = value; - return s; - } - } - - MDSPAN_INLINE_FUNCTION constexpr index_type - required_span_size() const noexcept { - if constexpr (extents_type::rank() == 0) { - return 1; - } else if constexpr (extents_type::rank() == 1) { - return exts.extent(0); - } else { - index_type value = 1; - for (rank_type r = 0; r < extent_to_pad_idx; ++r) { - value *= exts.extent(r); - } - return value * padded_stride.value(0); - } - } - - /** - * Return the mapping given the provided indices per rank. - * - * This overload participates in overload resolution only if: - * - `sizeof...(Indices) == extents_type::rank()`, - * - `(is_convertible_v<Indices, index_type> && ...) is true`, and - * - (is_nothrow_constructible_v<index_type, Indices> && ...) is true. - */ - MDSPAN_TEMPLATE_REQUIRES( - class... _Indices, - /* requires */ (sizeof...(_Indices) == extents_type::rank() && - (::MDSPAN_IMPL_STANDARD_NAMESPACE::detail:: - are_valid_indices<index_type, _Indices...>()))) - MDSPAN_INLINE_FUNCTION constexpr size_t - operator()(_Indices... idxs) const noexcept { - return compute_offset(std::index_sequence_for<_Indices...>{}, idxs...); - } - - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_unique() noexcept { - return true; - } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_exhaustive() noexcept { - return (extents_type::rank() <= rank_type(1)) || - (extents_type::static_extent(extent_to_pad_idx) != dynamic_extent && - extents_type::static_extent(extent_to_pad_idx) == - padded_stride_type::static_value()); - } - MDSPAN_INLINE_FUNCTION static constexpr bool is_always_strided() noexcept { - return true; - } - - MDSPAN_INLINE_FUNCTION static constexpr bool is_unique() noexcept { - return true; - } - MDSPAN_INLINE_FUNCTION constexpr bool is_exhaustive() const noexcept { - return (extents_type::rank() < 2) || - (exts.extent(extent_to_pad_idx) == padded_stride.value(0)); - } - MDSPAN_INLINE_FUNCTION static constexpr bool is_strided() noexcept { - return true; - } - - MDSPAN_INLINE_FUNCTION constexpr index_type - stride(rank_type r) const noexcept { - assert(r < extents_type::rank()); - if (r == extents_type::rank() - 1) - return index_type(1); - - index_type value = padded_stride.value(0); - for (rank_type k = extents_type::rank() - 2; k > r; k--) - value *= exts.extent(k); - - return value; - } - - /** - * Equality operator between `layout_right_padded`s - * - * This overload only participates in overload resolution if - * `OtherExtents::rank() == extents_type::rank()`. - * - * \note There is currently a difference from p2642r2, where this function is - * specified as taking `layout_right_padded< padding_value >::mapping< - * Extents>`. However, this makes `padding_value` non-deducible. - */ - MDSPAN_TEMPLATE_REQUIRES( - class _Mapping, - /* requires */ (detail::is_layout_right_padded_mapping<_Mapping>::value && - (_Mapping::extents_type::rank() == extents_type::rank()))) - MDSPAN_INLINE_FUNCTION friend constexpr bool - operator==(const mapping &left, const _Mapping &right) noexcept { - // Workaround for some compilers not short-circuiting properly with - // compile-time checks i.e. we can't access stride(_padding_stride_idx) of a - // rank 0 mapping - bool strides_equal = true; - if constexpr (extents_type::rank() > rank_type(1)) { - strides_equal = - left.stride(padded_stride_idx) == right.stride(padded_stride_idx); - } - return (left.extents() == right.extents()) && strides_equal; - } - -#if !MDSPAN_HAS_CXX_20 - /** - * Inequality operator between `layout_right_padded`s - * - * This overload only participates in overload resolution if - * `OtherExtents::rank() == extents_type::rank()`. - */ - MDSPAN_TEMPLATE_REQUIRES( - class _Mapping, - /* requires */ (detail::is_layout_right_padded_mapping<_Mapping>::value && - (_Mapping::extents_type::rank() == extents_type::rank()))) - MDSPAN_INLINE_FUNCTION friend constexpr bool - operator!=(const mapping &left, const _Mapping &right) noexcept { - return !(left == right); - } -#endif -}; -} -} diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/__p2642_bits/layout_padded_fwd.hpp b/tests/generator_scripts/deps/mdspan/include/experimental/__p2642_bits/layout_padded_fwd.hpp deleted file mode 100644 index b5eaac952bc8998c9d9710d8c46004f3c5da6b10..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/__p2642_bits/layout_padded_fwd.hpp +++ /dev/null @@ -1,131 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER -#pragma once - -#include <cassert> -#include "../__p0009_bits/dynamic_extent.hpp" -#include "../__p0009_bits/utility.hpp" - -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { -namespace MDSPAN_IMPL_PROPOSED_NAMESPACE { - -template <size_t padding_value = dynamic_extent> -struct layout_left_padded { - template <class _Extents> - class mapping; -}; - -template <size_t padding_value = dynamic_extent> -struct layout_right_padded { - template <class _Extents> - class mapping; -}; - -namespace detail { -// The layout_padded_constants structs are only useful if rank > 1, otherwise they may wrap -template <class _Layout, class _ExtentsType> -struct layout_padded_constants; - -template <class _ExtentsType, size_t _PaddingStride> -struct layout_padded_constants<layout_left_padded<_PaddingStride>, _ExtentsType> -{ - using rank_type = typename _ExtentsType::rank_type; - static constexpr rank_type padded_stride_idx = 1; - static constexpr rank_type extent_to_pad_idx = 0; -}; - -template <class _ExtentsType, size_t _PaddingStride> -struct layout_padded_constants<layout_right_padded<_PaddingStride>, _ExtentsType> -{ - using rank_type = typename _ExtentsType::rank_type; - static constexpr rank_type padded_stride_idx = _ExtentsType::rank() - 2; - static constexpr rank_type extent_to_pad_idx = _ExtentsType::rank() - 1; -}; - -template <class _Layout> -struct is_layout_left_padded : std::false_type {}; - -template <size_t _PaddingStride> -struct is_layout_left_padded<layout_left_padded<_PaddingStride>> : std::true_type {}; - -template <class _Mapping, class _Enabled = void> -struct is_layout_left_padded_mapping : std::false_type {}; - -template <class _Mapping> -struct is_layout_left_padded_mapping<_Mapping, - std::enable_if_t<std::is_same<_Mapping, typename layout_left_padded<_Mapping::padding_value>::template mapping<typename _Mapping::extents_type>>::value>> - : std::true_type {}; - -template <class _Layout> -struct is_layout_right_padded : std::false_type {}; - -template <size_t _PaddingStride> -struct is_layout_right_padded<layout_right_padded<_PaddingStride>> : std::true_type {}; - -template <class _Mapping, class _Enabled = void> -struct is_layout_right_padded_mapping : std::false_type {}; - -template <class _Mapping> -struct is_layout_right_padded_mapping<_Mapping, - std::enable_if_t<std::is_same<_Mapping, typename layout_right_padded<_Mapping::padding_value>::template mapping<typename _Mapping::extents_type>>::value>> - : std::true_type {}; - - -template <class _LayoutExtentsType, class _PaddedLayoutMappingType> -constexpr void check_padded_layout_converting_constructor_mandates(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<0>) {} - -template <class _LayoutExtentsType, class _PaddedLayoutMappingType> -constexpr void check_padded_layout_converting_constructor_mandates(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<1>) {} - -template <class _LayoutExtentsType, class _PaddedLayoutMappingType, std::size_t N> -constexpr void check_padded_layout_converting_constructor_mandates(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<N>) -{ - using extents_type = typename _PaddedLayoutMappingType::extents_type; - constexpr auto padding_value = _PaddedLayoutMappingType::padding_value; - constexpr auto idx = layout_padded_constants<typename _PaddedLayoutMappingType::layout_type, _LayoutExtentsType >::extent_to_pad_idx; - - constexpr auto statically_determinable = - (_LayoutExtentsType::static_extent(idx) != dynamic_extent) && - (extents_type::static_extent(idx) != dynamic_extent) && - (padding_value != dynamic_extent); - - static_assert(not statically_determinable or - (padding_value == 0 - ? _LayoutExtentsType::static_extent(idx) == 0 - : _LayoutExtentsType::static_extent(idx) % padding_value == 0), - ""); -} - -template <typename _ExtentsType, typename _OtherMapping> -constexpr void check_padded_layout_converting_constructor_preconditions(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<0>, - const _OtherMapping&) {} -template <typename _ExtentsType, typename _OtherMapping> -constexpr void check_padded_layout_converting_constructor_preconditions(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<1>, - const _OtherMapping&) {} -template <typename _ExtentsType, typename _OtherMapping, std::size_t N> -constexpr void check_padded_layout_converting_constructor_preconditions(MDSPAN_IMPL_STANDARD_NAMESPACE::detail::with_rank<N>, - const _OtherMapping &other_mapping) { - constexpr auto padded_stride_idx = - layout_padded_constants<typename _OtherMapping::layout_type, - _ExtentsType>::padded_stride_idx; - constexpr auto extent_to_pad_idx = layout_padded_constants<typename _OtherMapping::layout_type, _ExtentsType>::extent_to_pad_idx; - MDSPAN_IMPL_PRECONDITION(other_mapping.stride(padded_stride_idx) == other_mapping.extents().extent(extent_to_pad_idx)); -} - - -} -} -} diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/mdarray b/tests/generator_scripts/deps/mdspan/include/experimental/mdarray deleted file mode 100644 index 642d1f5ad9e704ade699bbe89d97344c34e6d5a3..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/mdarray +++ /dev/null @@ -1,28 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER - -#pragma once - -#ifndef MDSPAN_IMPL_STANDARD_NAMESPACE - #define MDSPAN_IMPL_STANDARD_NAMESPACE std -#endif - -#ifndef MDSPAN_IMPL_PROPOSED_NAMESPACE - #define MDSPAN_IMPL_PROPOSED_NAMESPACE experimental -#endif - -#include "mdspan" -#include "../mdspan/mdarray.hpp" diff --git a/tests/generator_scripts/deps/mdspan/include/experimental/mdspan b/tests/generator_scripts/deps/mdspan/include/experimental/mdspan deleted file mode 100644 index e8ba715ec2fd7afad65627d2eb4b8fcc720b8a3e..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/experimental/mdspan +++ /dev/null @@ -1,39 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER - -#pragma once - -#ifndef MDSPAN_IMPL_STANDARD_NAMESPACE - #define MDSPAN_IMPL_STANDARD_NAMESPACE std -#endif - -#ifndef MDSPAN_IMPL_PROPOSED_NAMESPACE - #define MDSPAN_IMPL_PROPOSED_NAMESPACE experimental -#endif - -#include "../mdspan/mdspan.hpp" - -// backward compatibility import into experimental -namespace MDSPAN_IMPL_STANDARD_NAMESPACE { - namespace MDSPAN_IMPL_PROPOSED_NAMESPACE { - using ::MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan; - using ::MDSPAN_IMPL_STANDARD_NAMESPACE::extents; - using ::MDSPAN_IMPL_STANDARD_NAMESPACE::layout_left; - using ::MDSPAN_IMPL_STANDARD_NAMESPACE::layout_right; - using ::MDSPAN_IMPL_STANDARD_NAMESPACE::layout_stride; - using ::MDSPAN_IMPL_STANDARD_NAMESPACE::default_accessor; - } -} diff --git a/tests/generator_scripts/deps/mdspan/include/mdspan/mdarray.hpp b/tests/generator_scripts/deps/mdspan/include/mdspan/mdarray.hpp deleted file mode 100644 index fd8f61c52f1b1836aea89f653e263cd33537e218..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/mdspan/mdarray.hpp +++ /dev/null @@ -1,31 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER - -#ifndef MDARRAY_HPP_ -#define MDARRAY_HPP_ - -#ifndef MDSPAN_IMPL_STANDARD_NAMESPACE - #define MDSPAN_IMPL_STANDARD_NAMESPACE Kokkos -#endif - -#ifndef MDSPAN_IMPL_PROPOSED_NAMESPACE - #define MDSPAN_IMPL_PROPOSED_NAMESPACE Experimental -#endif - -#include "mdspan.hpp" -#include "../experimental/__p1684_bits/mdarray.hpp" - -#endif // MDARRAY_HPP_ diff --git a/tests/generator_scripts/deps/mdspan/include/mdspan/mdspan.hpp b/tests/generator_scripts/deps/mdspan/include/mdspan/mdspan.hpp deleted file mode 100644 index 4a0e354ffd02183e0c738c9c716c1228b3b180bc..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/deps/mdspan/include/mdspan/mdspan.hpp +++ /dev/null @@ -1,43 +0,0 @@ -//@HEADER -// ************************************************************************ -// -// Kokkos v. 4.0 -// Copyright (2022) National Technology & Engineering -// Solutions of Sandia, LLC (NTESS). -// -// Under the terms of Contract DE-NA0003525 with NTESS, -// the U.S. Government retains certain rights in this software. -// -// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions. -// See https://kokkos.org/LICENSE for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//@HEADER - -#ifndef MDSPAN_HPP_ -#define MDSPAN_HPP_ - -#ifndef MDSPAN_IMPL_STANDARD_NAMESPACE - #define MDSPAN_IMPL_STANDARD_NAMESPACE Kokkos -#endif - -#ifndef MDSPAN_IMPL_PROPOSED_NAMESPACE - #define MDSPAN_IMPL_PROPOSED_NAMESPACE Experimental -#endif - -#include "../experimental/__p0009_bits/default_accessor.hpp" -#include "../experimental/__p0009_bits/full_extent_t.hpp" -#include "../experimental/__p0009_bits/mdspan.hpp" -#include "../experimental/__p0009_bits/dynamic_extent.hpp" -#include "../experimental/__p0009_bits/extents.hpp" -#include "../experimental/__p0009_bits/layout_stride.hpp" -#include "../experimental/__p0009_bits/layout_left.hpp" -#include "../experimental/__p0009_bits/layout_right.hpp" -#include "../experimental/__p0009_bits/macros.hpp" -#if MDSPAN_HAS_CXX_17 -#include "../experimental/__p2642_bits/layout_padded.hpp" -#include "../experimental/__p2630_bits/submdspan.hpp" -#endif -#include "../experimental/__p2389_bits/dims.hpp" - -#endif // MDSPAN_HPP_ diff --git a/tests/generator_scripts/expected/SimpleClasses.h b/tests/generator_scripts/expected/SimpleClasses.h deleted file mode 100644 index 93e93cabdc7bc80331e2f5c7efc3a988f87e841a..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/expected/SimpleClasses.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include <cstdint> - -#define RESTRICT __restrict__ - -class Point { -public: - const int64_t & getX() const { - return this->x; - } -private: - int64_t x; - int64_t y; - int64_t z; -}; diff --git a/tests/generator_scripts/expected/Structural.h b/tests/generator_scripts/expected/Structural.h deleted file mode 100644 index 0eb1e25f0704e43172ef77b6cea7f022fd744c42..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/expected/Structural.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Expect the unexpected, and you shall never be surprised. - */ - -#pragma once - -#include <cstdint> - -#include <iostream> -#include "config.h" - -namespace awesome { - -#define RESTRICT __restrict__ -#define PI 3.1415 -using namespace std; - -} // namespace awesome diff --git a/tests/generator_scripts/expected/Variables.h b/tests/generator_scripts/expected/Variables.h deleted file mode 100644 index b6f2ce700b80d6e8c062208dc5239c67d2c728fc..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/expected/Variables.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <cstdint> - -#define RESTRICT __restrict__ - -class Scale { -private: - float alpha; -public: - Scale(float alpha) : alpha{ alpha } {} - void operator() (float *RESTRICT const _data_f, float *RESTRICT const _data_g); -}; diff --git a/tests/generator_scripts/index.yaml b/tests/generator_scripts/index.yaml new file mode 100644 index 0000000000000000000000000000000000000000..91bb77b99bd6e1dc8b9f7acfea936a8d8f97fa60 --- /dev/null +++ b/tests/generator_scripts/index.yaml @@ -0,0 +1,78 @@ +# This file acts as an index for the generator script test suite. +# For information about its structure and valid parameters, refer to the Readme.md in this folder. + +# Configuration + +TestConfigModule: + sfg-args: + file-extensions: [h++, c++] + config-module: "config/TestConfigModule_cfg.py" + +TestExtraCommandLineArgs: + sfg-args: + file-extensions: [h++, c++] + extra-args: [--precision, float32, test1, test2] + +TestIllegalArgs: + extra-args: [--sfg-file-extensionss, ".c++,.h++"] + expect-failure: true + +# Basic Composer Functionality + +BasicDefinitions: + sfg-args: + output-mode: header-only + expect-code: + hpp: + - regex: >- + #include\s\"config\.h\"\s* + namespace\s+awesome\s+{\s+.+\s+ + #define\sPI\s3\.1415\s+ + using\snamespace\sstd\;\s+ + }\s\/\/\s+namespace\sawesome + strip-whitespace: true + +SimpleClasses: + sfg-args: + output-mode: header-only + +Conditionals: + expect-code: + cpp: + - regex: switch\s*\(\s*noodle\s*\)\s*\{\s* + count: 2 + - regex: case\s+Noodles::[A-Z]+:\s*\{\s*.*\s*break;\s*\} + count: 2 + - regex: case\s+Noodles::[A-Z]+:\s*\{\s*return\s[0-9]+;\s*\} + count: 4 + - regex: if\s*\(\s*noodle\s==\sNoodles::RIGATONI\s\|\|\snoodle\s==\sNoodles::SPAGHETTI\s*\) + count: 1 + +# Kernel Generation + +ScaleKernel: +JacobiMdspan: +StlContainers1D: + +# SYCL + +SyclKernels: + sfg-args: + output-mode: inline + file-extensions: [hpp, ipp] + expect-code: + ipp: + - regex: >- + cgh\.parallel_for\(range,\s*\[=\]\s*\(const\s+sycl::item<\s*2\s*>\s+sycl_item\s*\)\s*\{\s*kernels::kernel\(.*\);\s*\}\); + +SyclBuffers: + compile: + cxx: icpx + cxx-flags: + - -fsycl + - -std=c++20 + - -Wall + - -Werror + link-flags: + - -fsycl + skip-if-not-found: true diff --git a/tests/generator_scripts/scripts/SimpleClasses.py b/tests/generator_scripts/scripts/SimpleClasses.py deleted file mode 100644 index 26c236f8a200658ee103150b6295f44fbae8647a..0000000000000000000000000000000000000000 --- a/tests/generator_scripts/scripts/SimpleClasses.py +++ /dev/null @@ -1,15 +0,0 @@ -from pystencilssfg import SourceFileGenerator - -with SourceFileGenerator() as sfg: - sfg.klass("Point")( - sfg.public( - sfg.method("getX", returns="const int64_t &", const=True, inline=True)( - "return this->x;" - ) - ), - sfg.private( - sfg.var("x", "int64_t"), - sfg.var("y", "int64_t"), - sfg.var("z", "int64_t") - ) - ) diff --git a/tests/generator_scripts/scripts/Structural.py b/tests/generator_scripts/source/BasicDefinitions.py similarity index 100% rename from tests/generator_scripts/scripts/Structural.py rename to tests/generator_scripts/source/BasicDefinitions.py diff --git a/tests/generator_scripts/source/Conditionals.py b/tests/generator_scripts/source/Conditionals.py new file mode 100644 index 0000000000000000000000000000000000000000..d1088a96925bf52ab3634cf439538ce1de2b58a7 --- /dev/null +++ b/tests/generator_scripts/source/Conditionals.py @@ -0,0 +1,49 @@ +from pystencilssfg import SourceFileGenerator + +with SourceFileGenerator() as sfg: + sfg.namespace("gen") + + sfg.include("<iostream>") + sfg.code(r"enum class Noodles { RIGATONI, RAMEN, SPAETZLE, SPAGHETTI };") + + noodle = sfg.var("noodle", sfg.cpptype("Noodles")) + + sfg.function("printOpinion")( + sfg.switch(noodle) + .case("Noodles::RAMEN")( + 'std::cout << "Great!" << std::endl;' + ) + .case("Noodles::SPAETZLE")( + 'std::cout << "Amazing!" << std::endl;' + ) + .default( + 'std::cout << "Okay, I guess..." << std::endl;' + ) + ) + + sfg.function("getRating", "int32")( + sfg.switch(noodle, autobreak=False) + .case("Noodles::RIGATONI")( + "return 13;" + ) + .case("Noodles::RAMEN")( + "return 41;" + ) + .case("Noodles::SPAETZLE")( + "return 43;" + ) + .case("Noodles::SPAGHETTI")( + "return 15;" + ), + "return 0;" + ) + + sfg.function("isItalian", return_type="bool")( + sfg.branch( + sfg.expr("{0} == Noodles::RIGATONI || {0} == Noodles::SPAGHETTI", noodle) + )( + "return true;" + )( + "return false;" + ) + ) diff --git a/tests/generator_scripts/source/JacobiMdspan.harness.cpp b/tests/generator_scripts/source/JacobiMdspan.harness.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e2b8c716bf1427b3e915d6eb6c9756e7127df893 --- /dev/null +++ b/tests/generator_scripts/source/JacobiMdspan.harness.cpp @@ -0,0 +1,25 @@ +#include "JacobiMdspan.hpp" + +#include <experimental/mdspan> +#include <memory> + +namespace stdex = std::experimental; + +using field_t = stdex::mdspan<double, stdex::extents< int64_t, std::dynamic_extent, std::dynamic_extent>>; +using scalar_field_t = stdex::mdspan<double, stdex::extents< int64_t, std::dynamic_extent, std::dynamic_extent, 1>>; + +int main(void) +{ + auto data_f = std::make_unique<double[]>(64); + scalar_field_t f{ data_f.get(), 8, 8 }; + + auto data_u = std::make_unique<double[]>(64); + field_t u{ data_u.get(), 8, 8 }; + + auto data_u_tmp = std::make_unique<double[]>(64); + field_t u_tmp{ data_u_tmp.get(), 8, 8 }; + + double h { 1.0 / 7.0 }; + + gen::jacobi_smooth(f, h, u_tmp, u); +} diff --git a/tests/generator_scripts/scripts/SimpleJacobi.py b/tests/generator_scripts/source/JacobiMdspan.py similarity index 62% rename from tests/generator_scripts/scripts/SimpleJacobi.py rename to tests/generator_scripts/source/JacobiMdspan.py index e84c872b05c354f4e1473b2eab17781f0880f035..41f149a8b36181a75728df2aa3d5819c53be8626 100644 --- a/tests/generator_scripts/scripts/SimpleJacobi.py +++ b/tests/generator_scripts/source/JacobiMdspan.py @@ -3,9 +3,13 @@ import sympy as sp from pystencils import fields, kernel from pystencilssfg import SourceFileGenerator -from pystencilssfg.lang.cpp import mdspan_ref +from pystencilssfg.lang.cpp.std import mdspan + +mdspan.configure(namespace="std::experimental", header="<experimental/mdspan>") with SourceFileGenerator() as sfg: + sfg.namespace("gen") + u_src, u_dst, f = fields("u_src, u_dst, f(1) : double[2D]", layout="fzyx") h = sp.Symbol("h") @@ -16,8 +20,8 @@ with SourceFileGenerator() as sfg: poisson_kernel = sfg.kernels.create(poisson_jacobi) sfg.function("jacobi_smooth")( - sfg.map_field(u_src, mdspan_ref(u_src)), - sfg.map_field(u_dst, mdspan_ref(u_dst)), - sfg.map_field(f, mdspan_ref(f)), + sfg.map_field(u_src, mdspan.from_field(u_src)), + sfg.map_field(u_dst, mdspan.from_field(u_dst)), + sfg.map_field(f, mdspan.from_field(f)), sfg.call(poisson_kernel) ) diff --git a/tests/generator_scripts/source/ScaleKernel.harness.cpp b/tests/generator_scripts/source/ScaleKernel.harness.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5e70096a50d1bd3bcd5e48ea5f3fd2cdc9040d35 --- /dev/null +++ b/tests/generator_scripts/source/ScaleKernel.harness.cpp @@ -0,0 +1,27 @@ +#include "ScaleKernel.hpp" + +#include <vector> + +#define NDEBUG +#include <cassert> + +int main(void){ + std::vector< float > src; + src.resize(gen::N); + + std::vector< float > dst; + dst.resize(gen::N); + + for(int i = 0; i < gen::N; ++i){ + src[i] = 1.0f; + } + + float alpha = 2.5f; + + gen::Scale scale{ alpha }; + scale(dst.data(), src.data()); + + for(int i = 0; i < gen::N; ++i){ + assert( dst[i] == alpha ); + } +} diff --git a/tests/generator_scripts/scripts/Variables.py b/tests/generator_scripts/source/ScaleKernel.py similarity index 66% rename from tests/generator_scripts/scripts/Variables.py rename to tests/generator_scripts/source/ScaleKernel.py index bcc85e4cba1b75364b500628b8b10fdb24a7470c..8bcc75fb7c98e8d46602c7f3f888650d8b8e011c 100644 --- a/tests/generator_scripts/scripts/Variables.py +++ b/tests/generator_scripts/source/ScaleKernel.py @@ -3,19 +3,23 @@ from pystencils import TypedSymbol, fields, kernel from pystencilssfg import SourceFileGenerator with SourceFileGenerator() as sfg: + N = 10 α = TypedSymbol("alpha", "float32") - f, g = fields("f, g: float32[10]") + src, dst = fields(f"src, dst: float32[{N}]") @kernel def scale(): - f[0] @= α * g.center() + src[0] @= α * dst.center() khandle = sfg.kernels.create(scale) + sfg.namespace("gen") + sfg.code(f"constexpr int N = {N};") + sfg.klass("Scale")( sfg.private(α), sfg.public( - sfg.constructor(α).init(α)(α.name), + sfg.constructor(α).init(α)(α), sfg.method("operator()")(sfg.init(α)(f"this->{α}"), sfg.call(khandle)), ), ) diff --git a/tests/generator_scripts/source/SimpleClasses.harness.cpp b/tests/generator_scripts/source/SimpleClasses.harness.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ecfc065f2fc27423403dab1c0b03200af766a4d7 --- /dev/null +++ b/tests/generator_scripts/source/SimpleClasses.harness.cpp @@ -0,0 +1,10 @@ +#include "SimpleClasses.hpp" + +#define NDEBUG +#include <cassert> + +int main(void){ + Point p { 3, 1, -4 }; + + assert(p.getX() == 3); +} diff --git a/tests/generator_scripts/source/SimpleClasses.py b/tests/generator_scripts/source/SimpleClasses.py new file mode 100644 index 0000000000000000000000000000000000000000..64093f5744c61918bf505518e2c39dffbb525fad --- /dev/null +++ b/tests/generator_scripts/source/SimpleClasses.py @@ -0,0 +1,28 @@ +from pystencilssfg import SourceFileGenerator + +with SourceFileGenerator() as sfg: + x_ = sfg.var("x_", "int64_t") + y_ = sfg.var("y_", "int64_t") + z_ = sfg.var("z_", "int64_t") + + x = sfg.var("x", "int64_t") + y = sfg.var("y", "int64_t") + z = sfg.var("z", "int64_t") + + sfg.klass("Point")( + sfg.public( + sfg.constructor(x, y, z) + .init(x_)(x) + .init(y_)(y) + .init(z_)(z), + + sfg.method("getX", returns="const int64_t &", const=True, inline=True)( + "return this->x_;" + ) + ), + sfg.private( + x_, + y_, + z_ + ) + ) diff --git a/tests/generator_scripts/source/StlContainers1D.harness.cpp b/tests/generator_scripts/source/StlContainers1D.harness.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d05fd4a34a4167451b059f18480eec5dfbaaf459 --- /dev/null +++ b/tests/generator_scripts/source/StlContainers1D.harness.cpp @@ -0,0 +1,85 @@ +#include "StlContainers1D.hpp" + +#include <iostream> +#include <span> +#include <vector> +#include <random> +#include <cmath> +#include <memory> + +#ifdef NDEBUG +#undef NDEBUG +#include <cassert> +#define NDEBUG +#else +#include <cassert> +#endif + +namespace StlContainers1D +{ + constexpr size_t N{974}; + constexpr double one_third { 1.0 / 3.0 }; + + void test_vector_kernel() + { + std::random_device rd; + std::mt19937 gen{ rd() }; + std::uniform_real_distribution<double> distrib{-1.0, 1.0}; + + std::vector<double> src; + std::vector<double> dst; + + src.resize(N); + dst.resize(N); + + for (size_t i = 0; i < N; ++i) + { + src[i] = distrib(gen); + dst[i] = 0.0; + } + + gen::averageVector(dst, src); + + for (size_t i = 1; i < N - 1; ++i) + { + const double desired = one_third * ( src[i - 1] + src[i] + src[i + 1] ); + assert( std::abs(desired - dst[i]) < 1e-12 ); + } + } + + void test_span_kernel() + { + std::random_device rd; + std::mt19937 gen{ rd() }; + std::uniform_real_distribution<double> distrib{-1.0, 1.0}; + + auto src_data = std::make_unique< double[] >(N); + auto dst_data = std::make_unique< double[] >(N); + + std::span< double > src{ src_data.get(), N }; + std::span< double > dst{ dst_data.get(), N }; + + for (size_t i = 0; i < N; ++i) + { + src[i] = distrib(gen); + dst[i] = 0.0; + } + + gen::averageSpan(dst, src); + + for (size_t i = 1; i < N - 1; ++i) + { + const double desired = one_third * ( src[i - 1] + src[i] + src[i + 1] ); + assert( std::abs(desired - dst[i]) < 1e-12 ); + } + } + +} + + +int main(void) +{ + StlContainers1D::test_vector_kernel(); + StlContainers1D::test_span_kernel(); + return 0; +} diff --git a/tests/generator_scripts/source/StlContainers1D.py b/tests/generator_scripts/source/StlContainers1D.py new file mode 100644 index 0000000000000000000000000000000000000000..3f6ec2c953a6537bef9785d837a2def88439972a --- /dev/null +++ b/tests/generator_scripts/source/StlContainers1D.py @@ -0,0 +1,30 @@ +import pystencils as ps +import sympy as sp + +from pystencilssfg import SourceFileGenerator +from pystencilssfg.lang.cpp import std + + +with SourceFileGenerator() as sfg: + sfg.namespace("StlContainers1D::gen") + + src, dst = ps.fields("src, dst: double[1D]") + + asms = [ + ps.Assignment(dst[0], sp.Rational(1, 3) * (src[-1] + src[0] + src[1])) + ] + + kernel = sfg.kernels.create(asms, "average") + + sfg.function("averageVector")( + sfg.map_field(src, std.vector.from_field(src)), + sfg.map_field(dst, std.vector.from_field(dst)), + sfg.call(kernel) + ) + + sfg.function("averageSpan")( + sfg.map_field(src, std.span.from_field(src)), + sfg.map_field(dst, std.span.from_field(dst)), + sfg.call(kernel) + ) + diff --git a/tests/generator_scripts/source/SyclBuffers.harness.cpp b/tests/generator_scripts/source/SyclBuffers.harness.cpp new file mode 100644 index 0000000000000000000000000000000000000000..01d368f6d70d8b7b6c850f048113518a70801199 --- /dev/null +++ b/tests/generator_scripts/source/SyclBuffers.harness.cpp @@ -0,0 +1,23 @@ +#include <sycl/sycl.hpp> +#include <iostream> + +#include "SyclBuffers.hpp" + +int main(void) { + sycl::queue queue; + { + sycl::range< 2 > domainSize { 64, 64 }; + const double h { 1.0 / 63.0 }; + sycl::buffer< double, 2 > u { domainSize }; + sycl::buffer< double, 2 > uTmp { domainSize }; + sycl::buffer< double, 2 > f { domainSize }; + + queue.submit([&](sycl::handler & cgh){ + sycl::accessor uAcc { u, cgh }; + sycl::accessor uTmpAcc { uTmp, cgh }; + sycl::accessor fAcc { f, cgh }; + + gen::jacobiUpdate(fAcc, h, cgh, domainSize, uTmpAcc, uAcc); + }); + } +} diff --git a/tests/generator_scripts/scripts/TestSyclBuffer.py b/tests/generator_scripts/source/SyclBuffers.py similarity index 78% rename from tests/generator_scripts/scripts/TestSyclBuffer.py rename to tests/generator_scripts/source/SyclBuffers.py index d041756a08f07f74815366a09b79310eb2c5cca6..36234a84286a561ea4c18e4810aa5e49a5416c26 100644 --- a/tests/generator_scripts/scripts/TestSyclBuffer.py +++ b/tests/generator_scripts/source/SyclBuffers.py @@ -1,12 +1,12 @@ import pystencils as ps import sympy as sp from pystencilssfg import SourceFileGenerator -from pystencilssfg.lang.cpp.sycl_accessor import sycl_accessor_ref import pystencilssfg.extensions.sycl as sycl with SourceFileGenerator() as sfg: sfg = sycl.SyclComposer(sfg) + sfg.namespace("gen") u_src, u_dst, f = ps.fields("u_src, u_dst, f : double[2D]", layout="fzyx") h = sp.Symbol("h") @@ -25,9 +25,9 @@ with SourceFileGenerator() as sfg: cgh = sfg.sycl_handler("handler") rang = sfg.sycl_range(2, "range") mappings = [ - sfg.map_field(u_src, sycl_accessor_ref(u_src)), - sfg.map_field(u_dst, sycl_accessor_ref(u_dst)), - sfg.map_field(f, sycl_accessor_ref(f)), + sfg.map_field(u_src, sycl.accessor.from_field(u_src)), + sfg.map_field(u_dst, sycl.accessor.from_field(u_dst)), + sfg.map_field(f, sycl.accessor.from_field(f)), ] sfg.function("jacobiUpdate")( diff --git a/tests/generator_scripts/source/SyclKernels.py b/tests/generator_scripts/source/SyclKernels.py new file mode 100644 index 0000000000000000000000000000000000000000..841774383de6c11f7fcc893d694a8ff7d0f33205 --- /dev/null +++ b/tests/generator_scripts/source/SyclKernels.py @@ -0,0 +1,34 @@ +import sympy as sp +import pystencils as ps + +from pystencilssfg import SourceFileGenerator, SfgConfig, OutputMode +from pystencilssfg.extensions.sycl import SyclComposer + +cfg = SfgConfig() +cfg.output_mode = OutputMode.INLINE +cfg.extensions.impl = "ipp" + +with SourceFileGenerator(cfg) as sfg: + sfg = SyclComposer(sfg) + + u_src, u_dst, f = ps.fields("u_src, u_dst, f: double[10, 10]", layout="fzyx") + h = sp.Rational(1, 4) + + @ps.kernel + def poisson_jacobi(): + u_dst[0,0] @= (h**2 * f[0, 0] + u_src[1, 0] + u_src[-1, 0] + u_src[0, 1] + u_src[0, -1]) / 4 + + gen_config = ps.CreateKernelConfig( + target=ps.Target.SYCL + ) + + poisson_kernel = sfg.kernels.create(poisson_jacobi, config=gen_config) + + cgh = sfg.sycl_handler("cgh") + rang = sfg.sycl_range(2, "range") + + sfg.function("invoke_parallel_for")( + cgh.parallel_for(rang)( + sfg.call(poisson_kernel) + ) + ) diff --git a/tests/generator_scripts/scripts/TestConfigModule.py b/tests/generator_scripts/source/TestConfigModule.py similarity index 100% rename from tests/generator_scripts/scripts/TestConfigModule.py rename to tests/generator_scripts/source/TestConfigModule.py diff --git a/tests/generator_scripts/scripts/TestExtraCommandLineArgs.py b/tests/generator_scripts/source/TestExtraCommandLineArgs.py similarity index 100% rename from tests/generator_scripts/scripts/TestExtraCommandLineArgs.py rename to tests/generator_scripts/source/TestExtraCommandLineArgs.py diff --git a/tests/generator_scripts/scripts/TestIllegalArgs.py b/tests/generator_scripts/source/TestIllegalArgs.py similarity index 100% rename from tests/generator_scripts/scripts/TestIllegalArgs.py rename to tests/generator_scripts/source/TestIllegalArgs.py diff --git a/tests/generator_scripts/config/TestConfigModule_cfg.py b/tests/generator_scripts/source/config/TestConfigModule_cfg.py similarity index 100% rename from tests/generator_scripts/config/TestConfigModule_cfg.py rename to tests/generator_scripts/source/config/TestConfigModule_cfg.py diff --git a/tests/generator_scripts/test_generator_scripts.py b/tests/generator_scripts/test_generator_scripts.py index 316e0e0f5a57aeb80f6c13ed23f39536ca1209ef..bba12af2374d9f0177b7ec76bc8777627da366fe 100644 --- a/tests/generator_scripts/test_generator_scripts.py +++ b/tests/generator_scripts/test_generator_scripts.py @@ -1,172 +1,263 @@ -import pytest +"""Test suite for generator scripts. + +For more information, refer to the `README.md` file in the same directory. +""" -from dataclasses import dataclass +import pytest -import os -from os import path +import pathlib +import yaml +import re import shutil +import warnings import subprocess -THIS_DIR = path.split(__file__)[0] -SCRIPTS_DIR = path.join(THIS_DIR, "scripts") -CONFIG_DIR = path.join(THIS_DIR, "config") -EXPECTED_DIR = path.join(THIS_DIR, "expected") +THIS_DIR = pathlib.Path(__file__).parent +DEPS_DIR = THIS_DIR / "deps" +MDSPAN_QUAL_PATH = "mdspan-mdspan-0.6.0/include/" -@dataclass -class ScriptInfo: - @staticmethod - def make(name, *args, **kwargs): - return pytest.param(ScriptInfo(name, *args, **kwargs), id=f"{name}.py") - script_name: str - """Name of the generator script, without .py-extension. +TEST_INDEX = THIS_DIR / "index.yaml" +SOURCE_DIR = THIS_DIR / "source" +EXPECTED_DIR = THIS_DIR / "expected" +CXX_INCLUDE_FLAGS = ["-I", f"{DEPS_DIR}/{MDSPAN_QUAL_PATH}"] - Generator scripts must be located in the ``scripts`` folder. - """ - expected_outputs: tuple[str, ...] - """List of file extensions expected to be emitted by the generator script. +def prepare_deps(): + mdspan_archive_url = ( + "https://github.com/kokkos/mdspan/archive/refs/tags/mdspan-0.6.0.zip" + ) + mdspan_path = DEPS_DIR / MDSPAN_QUAL_PATH - Output files will all be placed in the ``out`` folder. - """ + import fasteners - args: tuple[str, ...] = () - """Command-line arguments to be passed to the generator script""" + with fasteners.InterProcessLock(THIS_DIR / ".get-deps.lock"): + if not mdspan_path.exists(): + DEPS_DIR.mkdir(parents=True, exist_ok=True) + print("Downloading mdspan reference implementation...") - should_fail: bool = False - """Whether the exeuction of this script should fail.""" + import requests + import tempfile + from zipfile import ZipFile - compilable_output: str | None = None - """File extension of the output file that can be compiled. + server_resp = requests.get(mdspan_archive_url) + with tempfile.TemporaryFile() as tmpfile: + tmpfile.write(server_resp.content) - If this is set, and the expected file exists, the ``compile_cmd`` will be - executed to check for error-free compilation of the output. - """ + with ZipFile(tmpfile) as archive: + for name in archive.namelist(): + if name.startswith(MDSPAN_QUAL_PATH): + archive.extract(name, DEPS_DIR) - compile_cmd: str = f"g++ --std=c++17 -I {THIS_DIR}/deps/mdspan/include" - """Command to be invoked to compile the generated source file.""" - def __repr__(self) -> str: - return self.script_name +class GenScriptTest: + @classmethod + def make(cls, name, test_description: dict): + return pytest.param(cls(name, test_description), id=f"{name}.py") + def __init__(self, name: str, test_description: dict): + self._name = name + script_path = SOURCE_DIR / f"{name}.py" -"""Scripts under test. + if not script_path.exists(): + raise ValueError(f"Script {script_path.name} does not exist.") -When adding new generator scripts to the `scripts` directory, -do not forget to include them here. -""" -SCRIPTS = [ - ScriptInfo.make( - "TestConfigModule", - ("h++", "c++"), - args=( - "--sfg-file-extensions", - ".c++,.h++", - "--sfg-config-module", - path.join(CONFIG_DIR, "TestConfigModule_cfg.py"), - ), - ), - ScriptInfo.make( - "TestIllegalArgs", - ("h++", "c++"), - args=( - "--sfg-file-extensionss", - ".c++,.h++", - ), - should_fail=True, - ), - ScriptInfo.make( - "TestExtraCommandLineArgs", - ("h++", "c++"), - args=( - "--sfg-file-extensions", - ".c++,.h++", - "--precision", - "float32", - "test1", - "test2", - ), - ), - ScriptInfo.make("Structural", ("hpp", "cpp")), - ScriptInfo.make("SimpleJacobi", ("hpp", "cpp"), compilable_output="cpp"), - ScriptInfo.make("SimpleClasses", ("hpp", "cpp")), - ScriptInfo.make("Variables", ("hpp", "cpp"), compilable_output="cpp"), - ScriptInfo.make( - "TestSyclBuffer", - ("hpp", "cpp"), - compilable_output="cpp" if shutil.which("icpx") else None, - compile_cmd="icpx -fsycl -std=c++20" if shutil.which("icpx") else "", - ), -] - - -@pytest.mark.parametrize("script_info", SCRIPTS) -def test_generator_script(script_info: ScriptInfo): - """Test a generator script defined by ``script_info``. - - The generator script will be run, with its output placed in the ``out`` folder. - If it is successful, its output files will be compared against - any files of the same name from the ``expected`` folder. - Finally, if any compilable files are specified, the test will attempt to compile them. - """ - - script_name = script_info.script_name - script_file = path.join(SCRIPTS_DIR, script_name + ".py") - - output_dir = path.join(THIS_DIR, "out", script_name) - if path.exists(output_dir): - shutil.rmtree(output_dir) - os.makedirs(output_dir, exist_ok=True) - - args = ["python", script_file, "--sfg-output-dir", output_dir] + list( - script_info.args - ) + self._script_path = script_path - result = subprocess.run(args) + self._output_dir: pathlib.Path + self._script_args = [] - if script_info.should_fail: - if result.returncode == 0: - pytest.fail( - f"Generator script {script_name} was supposed to fail, but didn't." - ) - return + expected_extensions = ["cpp", "hpp"] - if result.returncode != 0: - pytest.fail(f"Generator script {script_name} failed.") + sfg_args: dict = test_description.get("sfg-args", dict()) - # Check generated files - expected_files = set( - [f"{script_name}.{ext}" for ext in script_info.expected_outputs] - ) - output_files = set(os.listdir(output_dir)) - assert output_files == expected_files + if (output_mode := sfg_args.get("output-mode", None)) is not None: + if output_mode == "header-only": + expected_extensions = ["hpp"] + + self._script_args += ["--sfg-output-mode", output_mode] + + if (file_exts := sfg_args.get("file-extensions", None)) is not None: + expected_extensions = file_exts + self._script_args += ["--sfg-file-extensions", ",".join(file_exts)] - # Check against expected output - for ofile in output_files: - expected_file = path.join(EXPECTED_DIR, ofile) - actual_file = path.join(output_dir, ofile) + if (config_module := sfg_args.get("config-module", None)) is not None: + config_module = SOURCE_DIR / config_module + self._script_args += ["--sfg-config-module", str(config_module)] - if not path.exists(expected_file): - continue + self._script_args += test_description.get("extra-args", []) - with open(expected_file, "r") as f: - expected = f.read() + self._expected_extensions = test_description.get( + "expected-output", expected_extensions + ) - with open(actual_file, "r") as f: - actual = f.read() + self._expect_failure = test_description.get("expect-failure", False) - # Strip whitespace - expected = "".join(expected.split()) - actual = "".join(actual.split()) + self._expected_files: set[str] = set() + self._files_to_compile: list[str] = [] - assert expected == actual + for ext in self._expected_extensions: + fname = f"{self._name}.{ext}" + self._expected_files.add(fname) + if ext in ("cpp", "cxx", "c++"): + self._files_to_compile.append(fname) - # Check if output compiles - if (ext := script_info.compilable_output) is not None: - compilable_file = f"{script_name}.{ext}" - compile_args = script_info.compile_cmd.split() + ["-c", compilable_file] - compile_result = subprocess.run(compile_args, cwd=output_dir) + compile_descr: dict = test_description.get("compile", dict()) + cxx_compiler: str = compile_descr.get("cxx", "g++") - if compile_result.returncode != 0: - raise AssertionError("Compilation of generated files failed.") + skip_if_no_compiler: bool = compile_descr.get("skip-if-not-found", False) + cxx_options: list[str] = compile_descr.get( + "cxx-flags", ["--std=c++20", "-Wall", "-Werror"] + ) + link_options: list[str] = compile_descr.get("link-flags", []) + + self._compile_cmd: list[str] | None + self._link_cmd: list[str] | None + + if shutil.which(cxx_compiler) is None: + if skip_if_no_compiler: + warnings.warn( + f"[Test/{self._name}] Requested compiler {cxx_compiler} is not available." + ) + self._compile_cmd = self._link_cmd = None + else: + pytest.fail(f"Requested compiler {cxx_compiler} is not available.") + else: + self._compile_cmd = ( + [cxx_compiler] + cxx_options + CXX_INCLUDE_FLAGS + ["-c"] + ) + self._link_cmd = [cxx_compiler] + link_options + + self._expect_code: dict = test_description.get("expect-code", dict()) + + harness_file = SOURCE_DIR / f"{self._name}.harness.cpp" + if harness_file.exists(): + self._harness = harness_file + else: + self._harness = None + + def run(self, output_dir: pathlib.Path): + self._output_dir = output_dir + + self.run_script() + + if self._expect_failure: + return + + self.check_output_files() + self.compile_files() + self.run_harness() + + def run_script(self): + args = [ + "python", + str(self._script_path), + "--sfg-output-dir", + str(self._output_dir), + ] + list(self._script_args) + result = subprocess.run(args) + + if self._expect_failure: + if result.returncode == 0: + pytest.fail( + f"Generator script {self._script_path.name} was expected to fail, but didn't." + ) + elif result.returncode != 0: + pytest.fail(f"Generator script {self._script_path.name} failed.") + + def check_output_files(self): + output_files = set(p.name for p in self._output_dir.iterdir()) + assert output_files == self._expected_files + + for fp in self._output_dir.iterdir(): + self.check_file(fp) + + def check_file(self, actual_file: pathlib.Path): + with actual_file.open("r") as f: + actual_code = f.read() + + extension = actual_file.name.split(".")[1] + if (expectations := self._expect_code.get(extension, None)) is not None: + for expectation in expectations: + if isinstance(expectation, str): + assert ( + expectation in actual_code + ), f"Did not find expected code string in contents of {actual_file.name}:\n{expectation}" + elif isinstance(expectation, dict): + if (regex := expectation.get("regex", None)) is not None: + if expectation.get("strip-whitespace", False): + regex = "".join(regex.split()) + matcher = re.compile(regex) + count = expectation.get("count", 1) + findings = matcher.findall(actual_code) + assert len(findings) == count, ( + f"Regex {regex} matched incorrect number of times in generated code in {actual_file.name}:" + f"\nExpected {count}, got {len(findings)}" + ) + + def compile_files(self): + if self._compile_cmd is None: + return + + # Check if output compiles + for file in self._files_to_compile: + compile_args = self._compile_cmd + [file] + compile_result = subprocess.run(compile_args, cwd=str(self._output_dir)) + + if compile_result.returncode != 0: + cmd_str = " ".join(compile_args) + pytest.fail( + "Compilation of generated files failed: \n" + f" Command: {cmd_str}" + ) + + if self._harness is not None: + compile_args = self._compile_cmd + [ + "-I", + str(self._output_dir), + str(self._harness), + ] + compile_result = subprocess.run(compile_args, cwd=str(self._output_dir)) + + if compile_result.returncode != 0: + pytest.fail(f"Compilation of test harness for {self._name} failed.") + + def run_harness(self): + if self._compile_cmd is None: + return + + # Run after `compile`; i.e. for all compilable generated files, objects are already present + if self._harness is not None: + objects = self._output_dir.glob("*.o") + linker_args = self._link_cmd + [str(obj) for obj in objects] + linker_result = subprocess.run(linker_args, cwd=str(self._output_dir)) + + if linker_result.returncode != 0: + pytest.fail(f"Linking to test harness for {self._name} failed.") + + exe_args = "./a.out" + exe_result = subprocess.run(exe_args, cwd=str(self._output_dir)) + if exe_result.returncode != 0: + pytest.fail(f"Execution of test harness for {self._name} failed.") + + +def discover() -> list[GenScriptTest]: + with TEST_INDEX.open() as indexfile: + index = yaml.safe_load(indexfile.read()) + + tests = [] + for name, descr in index.items(): + if descr is None: + descr = dict() + tests.append(GenScriptTest.make(name, descr)) + return tests + + +DISCOVERED_TESTS = discover() + + +@pytest.mark.parametrize("test_descriptor", DISCOVERED_TESTS) +def test_generator_script(test_descriptor: GenScriptTest, tmp_path): + prepare_deps() + test_descriptor.run(tmp_path) diff --git a/tests/ir/test_postprocessing.py b/tests/ir/test_postprocessing.py index 6a38d91c5f21a074f09c0a51ca7db39c0e4cba5f..070743ae6ce7e63ce4c825142ed28fb6052d647f 100644 --- a/tests/ir/test_postprocessing.py +++ b/tests/ir/test_postprocessing.py @@ -80,7 +80,7 @@ def test_find_sympy_symbols(): assert call_tree.children[1].code_string == "const double y = x / a;" -class TestFieldExtraction(IFieldExtraction): +class DemoFieldExtraction(IFieldExtraction): def __init__(self, name: str): self.obj = AugExpr(PsCustomType("MyField")).var(name) @@ -108,7 +108,7 @@ def test_field_extraction(): khandle = sfg.kernels.create(set_constant) - extraction = TestFieldExtraction("f") + extraction = DemoFieldExtraction("f") call_tree = make_sequence(sfg.map_field(f, extraction, cast_indexing_symbols=False), sfg.call(khandle)) pp = CallTreePostProcessing() @@ -143,8 +143,8 @@ def test_duplicate_field_shapes(): khandle = sfg.kernels.create(set_constant) call_tree = make_sequence( - sfg.map_field(g, TestFieldExtraction("g"), cast_indexing_symbols=False), - sfg.map_field(f, TestFieldExtraction("f"), cast_indexing_symbols=False), + sfg.map_field(g, DemoFieldExtraction("g"), cast_indexing_symbols=False), + sfg.map_field(f, DemoFieldExtraction("f"), cast_indexing_symbols=False), sfg.call(khandle), ) diff --git a/tests/lang/test_cpp_stl_classes.py b/tests/lang/test_cpp_stl_classes.py new file mode 100644 index 0000000000000000000000000000000000000000..e400114c46f919e210c9968e7a417119a43a553b --- /dev/null +++ b/tests/lang/test_cpp_stl_classes.py @@ -0,0 +1,75 @@ +import pytest + +import pystencils as ps + +from pystencilssfg.lang.cpp import std +from pystencilssfg.lang import includes, HeaderFile + + +def no_spaces(s: str): + return "".join(s.split()) + + +def test_stl_containers(): + expr = std.vector("float64").var("numbers") + assert no_spaces(expr.get_dtype().c_string()) == "std::vector<double>" + assert includes(expr) == {HeaderFile.parse("<vector>")} + + expr = std.vector("float64", ref=True, const=True).var("numbers") + assert no_spaces(expr.get_dtype().c_string()) == "conststd::vector<double>&" + assert includes(expr) == {HeaderFile.parse("<vector>")} + + expr = std.tuple(("float64", "int32", "uint16", "bool")).var("t") + assert ( + no_spaces(expr.get_dtype().c_string()) + == "std::tuple<double,int32_t,uint16_t,bool>" + ) + assert includes(expr) == {HeaderFile.parse("<tuple>")} + + expr = std.span("uint16", ref=True).var("s") + assert no_spaces(expr.get_dtype().c_string()) == "std::span<uint16_t>&" + assert includes(expr) == {HeaderFile.parse("<span>")} + + +def test_vector_from_field(): + f = ps.fields("f: float32[1D]") + f_vec = std.vector.from_field(f) + + assert f_vec.element_type == ps.create_type("float32") + assert str(f_vec) == f.name + + f = ps.fields("f(1): float32[1D]") + f_vec = std.vector.from_field(f) + + assert f_vec.element_type == ps.create_type("float32") + assert str(f_vec) == f.name + + f = ps.fields("f(2): float32[1D]") + with pytest.raises(ValueError): + std.vector.from_field(f) + + f = ps.fields("f(1): float32[2D]") + with pytest.raises(ValueError): + std.vector.from_field(f) + + +def test_span_from_field(): + f = ps.fields("f: float32[1D]") + f_vec = std.span.from_field(f) + + assert f_vec.element_type == ps.create_type("float32") + assert str(f_vec) == f.name + + f = ps.fields("f(1): float32[1D]") + f_vec = std.span.from_field(f) + + assert f_vec.element_type == ps.create_type("float32") + assert str(f_vec) == f.name + + f = ps.fields("f(2): float32[1D]") + with pytest.raises(ValueError): + std.span.from_field(f) + + f = ps.fields("f(1): float32[2D]") + with pytest.raises(ValueError): + std.span.from_field(f) diff --git a/tests/lang/test_expressions.py b/tests/lang/test_expressions.py index ef2f1943c07b3f0e1a23750302f043c0ebe89105..f7cbebdf2d07a6a87edaaf0774ba393cf2264e06 100644 --- a/tests/lang/test_expressions.py +++ b/tests/lang/test_expressions.py @@ -1,7 +1,7 @@ import pytest from pystencilssfg import SfgException -from pystencilssfg.lang import asvar, SfgVar, AugExpr +from pystencilssfg.lang import asvar, SfgVar, AugExpr, cpptype, HeaderFile import sympy as sp @@ -93,3 +93,13 @@ def test_augexpr_illegal_format(): with pytest.raises(ValueError): # Cannot parse expressions containing symbols _ = AugExpr.format("{} + {}", x + 3, y / (2 * z)) + + +def test_headers(): + pairtype = cpptype("std::tuple< {}, {} >", "<tuple>") + + var = AugExpr(pairtype("double", "int")).var("x") + assert var.includes == {HeaderFile("tuple", system_header=True)} + + expr = AugExpr().bind("std::get< int >({})", var) + assert expr.includes == {HeaderFile("tuple", system_header=True)} diff --git a/tests/lang/test_sycl_accessor.py b/tests/lang/test_sycl_accessor.py index d2af2950a1bd2edf31f2da7086a29b8329339b00..feb6baefb0e000a92011c7ffa03c758cc9164b56 100644 --- a/tests/lang/test_sycl_accessor.py +++ b/tests/lang/test_sycl_accessor.py @@ -1,7 +1,7 @@ import pytest -from pystencilssfg.lang.cpp.sycl_accessor import sycl_accessor_ref +from pystencilssfg.lang.cpp import sycl import pystencils as ps @@ -9,8 +9,8 @@ import pystencils as ps @pytest.mark.parametrize("dim", [1, 2, 3]) def test_spatial_field(data_type, dim): f = ps.fields(f"f:{data_type}[{dim}D]") - ref = sycl_accessor_ref(f) - assert f"sycl::accessor< {data_type}, {dim} > &" in str(ref.get_dtype()) + ref = sycl.accessor.from_field(f) + assert f"sycl::accessor< {data_type}, {dim} >&" in str(ref.get_dtype()) @pytest.mark.parametrize("data_type", ["double", "float"]) @@ -18,7 +18,7 @@ def test_too_large_dim(data_type): dim = 4 f = ps.fields(f"f:{data_type}[{dim}D]") with pytest.raises(ValueError): - sycl_accessor_ref(f) + sycl.accessor.from_field(f) @pytest.mark.parametrize("data_type", ["double", "float"]) @@ -29,8 +29,8 @@ def test_index_field(data_type, spatial_dim, index_dims): total_dims = spatial_dim + index_dims f = ps.fields(f"f({', '.join(index_shape)}):{data_type}[{spatial_dim}D]") if total_dims <= 3: - ref = sycl_accessor_ref(f) - assert f"sycl::accessor< {data_type}, {total_dims} > &" in str(ref.get_dtype()) + ref = sycl.accessor.from_field(f) + assert f"sycl::accessor< {data_type}, {total_dims} >&" in str(ref.get_dtype()) else: with pytest.raises(ValueError): - sycl_accessor_ref(f) + sycl.accessor.from_field(f) diff --git a/tests/lang/test_types.py b/tests/lang/test_types.py new file mode 100644 index 0000000000000000000000000000000000000000..44b9a7c23a273b703a5c4d49386258f72bb2f726 --- /dev/null +++ b/tests/lang/test_types.py @@ -0,0 +1,14 @@ +from pystencilssfg.lang import cpptype, HeaderFile +from pystencils import create_type + + +def test_cpptypes(): + tclass = cpptype("std::vector< {T}, {Allocator} >", "<vector>") + + vec_type = tclass(T=create_type("float32"), Allocator="std::allocator< float >") + assert str(vec_type).strip() == "std::vector< float, std::allocator< float > >" + assert ( + tclass.includes + == vec_type.includes + == {HeaderFile("vector", system_header=True)} + )