diff --git a/bin/loopy b/bin/loopy index 8291bdd3bfe5c157fca5bc4ad60ced2839ae529f..f8de8f55aa8d44fd5fbe94b7099ae8f1a4dfcf40 100644 --- a/bin/loopy +++ b/bin/loopy @@ -64,7 +64,7 @@ def main(): help="Defaults to stdout ('-').", nargs='?') parser.add_argument("--lang", metavar="LANGUAGE", help="loopy|fortran") parser.add_argument("--target", choices=( - "opencl", "ispc", "ispc-occa", "c", "cuda"), + "opencl", "ispc", "ispc-occa", "c", "c-fortran", "cuda"), default="opencl") parser.add_argument("--name") parser.add_argument("--transform") @@ -86,6 +86,9 @@ def main(): elif args.target == "c": from loopy.target.c import CTarget target = CTarget() + elif args.target == "c-fortran": + from loopy.target.c import CTarget + target = CTarget(fortran_abi=True) elif args.target == "cuda": from loopy.target.cuda import CudaTarget target = CudaTarget() diff --git a/loopy/kernel/__init__.py b/loopy/kernel/__init__.py index 46888e620501785073e2abf58180a5c6c93109d1..d125b0dfa964688e60d02fae242f2f1876b22f87 100644 --- a/loopy/kernel/__init__.py +++ b/loopy/kernel/__init__.py @@ -1155,7 +1155,7 @@ class LoopKernel(RecordWithoutPickling): # {{{ persistent hash key generation / comparison - hash_fields = [ + hash_fields = ( "domains", "instructions", "args", @@ -1173,9 +1173,9 @@ class LoopKernel(RecordWithoutPickling): "options", "state", "target", - ] + ) - comparison_fields = hash_fields + [ + comparison_fields = hash_fields + ( # Contains pymbolic expressions, hence a (small) headache to hash. # Likely not needed for hash uniqueness => headache avoided. "applied_iname_rewrites", @@ -1189,7 +1189,7 @@ class LoopKernel(RecordWithoutPickling): "preamble_generators", "function_manglers", "symbol_manglers", - ] + ) def update_persistent_hash(self, key_hash, key_builder): """Custom hash computation function for use with diff --git a/loopy/target/__init__.py b/loopy/target/__init__.py index b8c903fc12cccde4e764731580cc8cfc04151af3..ee28594a50ce8486702e13f0ee9bf01debb4f859 100644 --- a/loopy/target/__init__.py +++ b/loopy/target/__init__.py @@ -30,8 +30,8 @@ class TargetBase(object): # {{{ persistent hashing - hash_fields = [] - comparison_fields = [] + hash_fields = () + comparison_fields = () def update_persistent_hash(self, key_hash, key_builder): for field_name in self.hash_fields: diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py index 0cf17992251778ee971298e736bd1080f6f36f13..73310c4db7ad590396377d1d757ebf8eb068a8e6 100644 --- a/loopy/target/c/__init__.py +++ b/loopy/target/c/__init__.py @@ -56,6 +56,13 @@ def _preamble_generator(kernel, seen_dtypes, seen_functions): class CTarget(TargetBase): + hash_fields = TargetBase.hash_fields + ("fortran_abi",) + comparison_fields = TargetBase.comparison_fields + ("fortran_abi",) + + def __init__(self, fortran_abi=False): + self.fortran_abi = fortran_abi + super(CTarget, self).__init__() + # {{{ types @memoize_method @@ -101,12 +108,16 @@ class CTarget(TargetBase): body, implemented_domains = kernel.target.generate_body( kernel, codegen_state) + name = kernel.name + if self.fortran_abi: + name += "_" + mod = Module([ FunctionBody( kernel.target.wrap_function_declaration( kernel, FunctionDeclaration( - Value("void", kernel.name), + Value("void", name), [iai.cgen_declarator for iai in impl_arg_info])), body) ]) @@ -234,7 +245,7 @@ class CTarget(TargetBase): def get_expression_to_code_mapper(self, codegen_state): from loopy.target.c.codegen.expression import LoopyCCodeMapper - return LoopyCCodeMapper(codegen_state) + return LoopyCCodeMapper(codegen_state, fortran_abi=self.fortran_abi) def wrap_temporary_decl(self, decl, is_local): return decl @@ -247,6 +258,11 @@ class CTarget(TargetBase): if not is_written: from cgen import Const result = Const(result) + + if self.fortran_abi: + from cgen import Pointer + result = Pointer(result) + return result def get_global_arg_decl(self, name, shape, dtype, is_written): diff --git a/loopy/target/c/codegen/expression.py b/loopy/target/c/codegen/expression.py index 2bf5c06bad405fba3a6a01f039cee0f4a133322c..d931ebf3373b7ab455787f5be7db7360cc042e66 100644 --- a/loopy/target/c/codegen/expression.py +++ b/loopy/target/c/codegen/expression.py @@ -42,13 +42,15 @@ from loopy.tools import is_integer # {{{ C code mapper class LoopyCCodeMapper(RecursiveMapper): - def __init__(self, codegen_state): + def __init__(self, codegen_state, fortran_abi=False): self.kernel = codegen_state.kernel self.codegen_state = codegen_state self.type_inf_mapper = TypeInferenceMapper(self.kernel) self.allow_complex = codegen_state.allow_complex + self.fortran_abi = fortran_abi + # {{{ helpers def infer_type(self, expr): @@ -108,6 +110,8 @@ class LoopyCCodeMapper(RecursiveMapper): "entry to loopy") def map_variable(self, expr, enclosing_prec, type_context): + prefix = "" + if expr.name in self.codegen_state.var_subst_map: if self.kernel.options.annotate_inames: return " /* %s */ %s" % ( @@ -131,12 +135,16 @@ class LoopyCCodeMapper(RecursiveMapper): raise RuntimeError("unsubscripted reference to array '%s'" % expr.name) + from loopy.kernel.data import ValueArg + if isinstance(arg, ValueArg) and self.fortran_abi: + prefix = "*" + result = self.kernel.mangle_symbol(expr.name) if result is not None: _, c_name = result - return c_name + return prefix + c_name - return expr.name + return prefix + expr.name def map_tagged_variable(self, expr, enclosing_prec, type_context): return expr.name diff --git a/loopy/version.py b/loopy/version.py index 4154c3a59cd2e2db383db3e4670ce55365ede1c1..2b35b55e073359992a483f494d56b8d3a912fd64 100644 --- a/loopy/version.py +++ b/loopy/version.py @@ -32,4 +32,4 @@ except ImportError: else: _islpy_version = islpy.version.VERSION_TEXT -DATA_MODEL_VERSION = "v17-islpy%s" % _islpy_version +DATA_MODEL_VERSION = "v18-islpy%s" % _islpy_version