From 84d3659ccb833f3d09c73c3776d56040b59c53c0 Mon Sep 17 00:00:00 2001 From: Kaushik Kulkarni Date: Tue, 22 Oct 2019 20:01:48 -0500 Subject: [PATCH 1/5] Adds C99 target - types would now correspond to those defined in inttypes - ExecutableCTarget derives from C99 as well --- loopy/__init__.py | 4 +- loopy/target/c/__init__.py | 76 ++++++++++++++++++++++++----------- loopy/target/c/c_execution.py | 3 +- 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/loopy/__init__.py b/loopy/__init__.py index d69a57bf1..6c52cc2e1 100644 --- a/loopy/__init__.py +++ b/loopy/__init__.py @@ -142,7 +142,7 @@ from loopy.frontend.fortran import (c_preprocess, parse_transformed_fortran, parse_fortran) from loopy.target import TargetBase, ASTBuilderBase -from loopy.target.c import CTarget, ExecutableCTarget, generate_header +from loopy.target.c import CTarget, C99Target, ExecutableCTarget, generate_header from loopy.target.cuda import CudaTarget from loopy.target.opencl import OpenCLTarget from loopy.target.pyopencl import PyOpenCLTarget @@ -271,7 +271,7 @@ __all__ = [ "LoopyError", "LoopyWarning", "TargetBase", - "CTarget", "ExecutableCTarget", "generate_header", + "CTarget", "C99Target", "ExecutableCTarget", "generate_header", "CudaTarget", "OpenCLTarget", "PyOpenCLTarget", "ISPCTarget", "NumbaTarget", "NumbaCudaTarget", diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py index 25b190809..c0cd0a940 100644 --- a/loopy/target/c/__init__.py +++ b/loopy/target/c/__init__.py @@ -77,6 +77,11 @@ class DTypeRegistryWrapper(object): # {{{ preamble generator +def c99_preamble_generator(preamble_info): + if any(dtype.is_integral() for dtype in preamble_info.seen_dtypes): + yield("10_inttypes", "#include ") + + def _preamble_generator(preamble_info): integer_type_names = ["int8", "int16", "int32", "int64"] @@ -368,29 +373,6 @@ class CTarget(TargetBase): # }}} -# {{{ executable c target - -class ExecutableCTarget(CTarget): - """ - An executable CTarget that uses (by default) JIT compilation of C-code - """ - - def __init__(self, compiler=None, fortran_abi=False): - super(ExecutableCTarget, self).__init__(fortran_abi=fortran_abi) - from loopy.target.c.c_execution import CCompiler - self.compiler = compiler or CCompiler() - - def get_kernel_executor(self, knl, *args, **kwargs): - from loopy.target.c.c_execution import CKernelExecutor - return CKernelExecutor(knl, compiler=self.compiler) - - def get_host_ast_builder(self): - # enable host code generation - return CASTBuilder(self) - -# }}} - - class _ConstRestrictPointer(Pointer): def get_decl_pair(self): sub_tp, sub_decl = self.subdecl.get_decl_pair() @@ -1080,4 +1062,52 @@ def generate_header(kernel, codegen_result=None): # }}} + +# {{{ C99 target + +class C99Target(CTarget): + def get_device_ast_builder(self): + return C99ASTBuilder(self) + + @memoize_method + def get_dtype_registry(self): + from loopy.target.c.compyte.dtypes import ( + DTypeRegistry, fill_registry_with_c_inttypes_types) + result = DTypeRegistry() + fill_registry_with_c_inttypes_types(result) + return DTypeRegistryWrapper(result) + + +class C99ASTBuilder(CASTBuilder): + def preamble_generators(self): + return ( + super(CASTBuilder, self).preamble_generators() + [ + c99_preamble_generator, + ]) + +# }}} + + +# {{{ executable c target + +class ExecutableCTarget(C99Target): + """ + An executable CTarget that uses (by default) JIT compilation of C-code + """ + + def __init__(self, compiler=None, fortran_abi=False): + super(ExecutableCTarget, self).__init__(fortran_abi=fortran_abi) + from loopy.target.c.c_execution import CCompiler + self.compiler = compiler or CCompiler() + + def get_kernel_executor(self, knl, *args, **kwargs): + from loopy.target.c.c_execution import CKernelExecutor + return CKernelExecutor(knl, compiler=self.compiler) + + def get_host_ast_builder(self): + # enable host code generation + return CASTBuilder(self) + +# }}} + # vim: foldmethod=marker diff --git a/loopy/target/c/c_execution.py b/loopy/target/c/c_execution.py index 60947c7f7..730bbd6e2 100644 --- a/loopy/target/c/c_execution.py +++ b/loopy/target/c/c_execution.py @@ -306,7 +306,8 @@ class IDIToCDLL(object): """ def __init__(self, target): self.target = target - self.registry = target.get_dtype_registry().wrapped_registry + from loopy.target.c import CTarget + self.registry = CTarget().get_dtype_registry().wrapped_registry def __call__(self, knl, idi): # next loop through the implemented data info to get the arg data -- GitLab From 450e05949ea6cf6b2be501a4f0e1d007cbc8f2df Mon Sep 17 00:00:00 2001 From: Kaushik Kulkarni Date: Tue, 22 Oct 2019 21:31:24 -0500 Subject: [PATCH 2/5] update compyte --- loopy/target/c/compyte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loopy/target/c/compyte b/loopy/target/c/compyte index 11dc00352..04eb2fc75 160000 --- a/loopy/target/c/compyte +++ b/loopy/target/c/compyte @@ -1 +1 @@ -Subproject commit 11dc00352423cddd71f09e809d0a22ab1c3ea7a5 +Subproject commit 04eb2fc75235593ddc609628cfb5ec1f9d9aa393 -- GitLab From 48bd92dca1ae083b256ab9998b05263d2bbfbb10 Mon Sep 17 00:00:00 2001 From: Kaushik Kulkarni Date: Tue, 22 Oct 2019 21:31:33 -0500 Subject: [PATCH 3/5] Renaming: - C(Target, ASTBuilder) -> CFamily(Target, ASTBuilder) - C99(Target, ASTBuilder) -> C(Target, ASTBuilder) --- loopy/__init__.py | 4 ++-- loopy/kernel/array.py | 2 +- loopy/library/reduction.py | 8 ++++---- loopy/target/__init__.py | 1 + loopy/target/c/__init__.py | 30 +++++++++++++++--------------- loopy/target/c/c_execution.py | 4 ++-- loopy/target/cuda.py | 6 +++--- loopy/target/ispc.py | 6 +++--- loopy/target/opencl.py | 6 +++--- 9 files changed, 34 insertions(+), 33 deletions(-) diff --git a/loopy/__init__.py b/loopy/__init__.py index 6c52cc2e1..a1c97d2f4 100644 --- a/loopy/__init__.py +++ b/loopy/__init__.py @@ -142,7 +142,7 @@ from loopy.frontend.fortran import (c_preprocess, parse_transformed_fortran, parse_fortran) from loopy.target import TargetBase, ASTBuilderBase -from loopy.target.c import CTarget, C99Target, ExecutableCTarget, generate_header +from loopy.target.c import CFamilyTarget, CTarget, ExecutableCTarget, generate_header from loopy.target.cuda import CudaTarget from loopy.target.opencl import OpenCLTarget from loopy.target.pyopencl import PyOpenCLTarget @@ -271,7 +271,7 @@ __all__ = [ "LoopyError", "LoopyWarning", "TargetBase", - "CTarget", "C99Target", "ExecutableCTarget", "generate_header", + "CFamilyTarget", "CTarget", "ExecutableCTarget", "generate_header", "CudaTarget", "OpenCLTarget", "PyOpenCLTarget", "ISPCTarget", "NumbaTarget", "NumbaCudaTarget", diff --git a/loopy/kernel/array.py b/loopy/kernel/array.py index 3588f38af..84b0a4a74 100644 --- a/loopy/kernel/array.py +++ b/loopy/kernel/array.py @@ -619,7 +619,7 @@ class ArrayBase(ImmutableRecord): If an integer N is given, the array would be declared with ``__attribute__((aligned(N)))`` in code generation for - :class:`loopy.CTarget`. + :class:`loopy.CFamilyTarget`. .. versionadded:: 2018.1 diff --git a/loopy/library/reduction.py b/loopy/library/reduction.py index 2658b8cd7..53d05a28e 100644 --- a/loopy/library/reduction.py +++ b/loopy/library/reduction.py @@ -448,8 +448,8 @@ def parse_reduction_op(name): def reduction_function_mangler(kernel, func_id, arg_dtypes): if isinstance(func_id, ArgExtOp): - from loopy.target.opencl import CTarget - if not isinstance(kernel.target, CTarget): + from loopy.target.opencl import CFamilyTarget + if not isinstance(kernel.target, CFamilyTarget): raise LoopyError("%s: only C-like targets supported for now" % func_id) op = func_id.reduction_op @@ -470,8 +470,8 @@ def reduction_function_mangler(kernel, func_id, arg_dtypes): ) elif isinstance(func_id, SegmentedOp): - from loopy.target.opencl import CTarget - if not isinstance(kernel.target, CTarget): + from loopy.target.opencl import CFamilyTarget + if not isinstance(kernel.target, CFamilyTarget): raise LoopyError("%s: only C-like targets supported for now" % func_id) op = func_id.reduction_op diff --git a/loopy/target/__init__.py b/loopy/target/__init__.py index a81354e2f..73d2a6328 100644 --- a/loopy/target/__init__.py +++ b/loopy/target/__init__.py @@ -31,6 +31,7 @@ __doc__ = """ .. autoclass:: TargetBase .. autoclass:: ASTBuilderBase +.. autoclass:: CFamilyTarget .. autoclass:: CTarget .. autoclass:: ExecutableCTarget .. autoclass:: CudaTarget diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py index c0cd0a940..1b7ca0826 100644 --- a/loopy/target/c/__init__.py +++ b/loopy/target/c/__init__.py @@ -319,7 +319,7 @@ class CExpression(object): # }}} -class CTarget(TargetBase): +class CFamilyTarget(TargetBase): """A target for plain "C", without any parallel extensions. """ @@ -328,7 +328,7 @@ class CTarget(TargetBase): def __init__(self, fortran_abi=False): self.fortran_abi = fortran_abi - super(CTarget, self).__init__() + super(CFamilyTarget, self).__init__() def split_kernel_at_global_barriers(self): return False @@ -337,7 +337,7 @@ class CTarget(TargetBase): return DummyHostASTBuilder(self) def get_device_ast_builder(self): - return CASTBuilder(self) + return CFamilyASTBuilder(self) # {{{ types @@ -466,24 +466,24 @@ def c_math_mangler(target, name, arg_dtypes, modify_name=True): # }}} -class CASTBuilder(ASTBuilderBase): +class CFamilyASTBuilder(ASTBuilderBase): # {{{ library def function_manglers(self): return ( - super(CASTBuilder, self).function_manglers() + [ + super(CFamilyASTBuilder, self).function_manglers() + [ c_math_mangler ]) def symbol_manglers(self): return ( - super(CASTBuilder, self).symbol_manglers() + [ + super(CFamilyASTBuilder, self).symbol_manglers() + [ c_symbol_mangler ]) def preamble_generators(self): return ( - super(CASTBuilder, self).preamble_generators() + [ + super(CFamilyASTBuilder, self).preamble_generators() + [ _preamble_generator, ]) @@ -1046,7 +1046,7 @@ def generate_header(kernel, codegen_result=None): functions. """ - if not isinstance(kernel.target, CTarget): + if not isinstance(kernel.target, CFamilyTarget): raise LoopyError( 'Header generation for non C-based languages are not implemented') @@ -1065,9 +1065,9 @@ def generate_header(kernel, codegen_result=None): # {{{ C99 target -class C99Target(CTarget): +class CTarget(CFamilyTarget): def get_device_ast_builder(self): - return C99ASTBuilder(self) + return CASTBuilder(self) @memoize_method def get_dtype_registry(self): @@ -1078,10 +1078,10 @@ class C99Target(CTarget): return DTypeRegistryWrapper(result) -class C99ASTBuilder(CASTBuilder): +class CASTBuilder(CFamilyASTBuilder): def preamble_generators(self): return ( - super(CASTBuilder, self).preamble_generators() + [ + super(CFamilyASTBuilder, self).preamble_generators() + [ c99_preamble_generator, ]) @@ -1090,9 +1090,9 @@ class C99ASTBuilder(CASTBuilder): # {{{ executable c target -class ExecutableCTarget(C99Target): +class ExecutableCTarget(CTarget): """ - An executable CTarget that uses (by default) JIT compilation of C-code + An executable CFamilyTarget that uses (by default) JIT compilation of C-code """ def __init__(self, compiler=None, fortran_abi=False): @@ -1106,7 +1106,7 @@ class ExecutableCTarget(C99Target): def get_host_ast_builder(self): # enable host code generation - return CASTBuilder(self) + return CFamilyASTBuilder(self) # }}} diff --git a/loopy/target/c/c_execution.py b/loopy/target/c/c_execution.py index 730bbd6e2..698507978 100644 --- a/loopy/target/c/c_execution.py +++ b/loopy/target/c/c_execution.py @@ -306,8 +306,8 @@ class IDIToCDLL(object): """ def __init__(self, target): self.target = target - from loopy.target.c import CTarget - self.registry = CTarget().get_dtype_registry().wrapped_registry + from loopy.target.c import CFamilyTarget + self.registry = CFamilyTarget().get_dtype_registry().wrapped_registry def __call__(self, knl, idi): # next loop through the implemented data info to get the arg data diff --git a/loopy/target/cuda.py b/loopy/target/cuda.py index 8f14738c3..50fd1026f 100644 --- a/loopy/target/cuda.py +++ b/loopy/target/cuda.py @@ -28,7 +28,7 @@ import numpy as np from pytools import memoize_method -from loopy.target.c import CTarget, CASTBuilder +from loopy.target.c import CFamilyTarget, CFamilyASTBuilder from loopy.target.c.codegen.expression import ExpressionToCExpressionMapper from loopy.diagnostic import LoopyError from loopy.types import NumpyType @@ -169,7 +169,7 @@ class ExpressionToCudaCExpressionMapper(ExpressionToCExpressionMapper): # {{{ target -class CudaTarget(CTarget): +class CudaTarget(CFamilyTarget): """A target for Nvidia's CUDA GPU programming language.""" def __init__(self, extern_c=True): @@ -216,7 +216,7 @@ class CudaTarget(CTarget): # {{{ ast builder -class CUDACASTBuilder(CASTBuilder): +class CUDACASTBuilder(CFamilyASTBuilder): # {{{ library def function_manglers(self): diff --git a/loopy/target/ispc.py b/loopy/target/ispc.py index cccee2301..eb0157bf8 100644 --- a/loopy/target/ispc.py +++ b/loopy/target/ispc.py @@ -26,7 +26,7 @@ THE SOFTWARE. import numpy as np # noqa -from loopy.target.c import CTarget, CASTBuilder +from loopy.target.c import CFamilyTarget, CFamilyASTBuilder from loopy.target.c.codegen.expression import ExpressionToCExpressionMapper from loopy.diagnostic import LoopyError from loopy.symbolic import Literal @@ -154,7 +154,7 @@ def fill_registry_with_ispc_types(reg, respect_windows, include_bool=True): # }}} -class ISPCTarget(CTarget): +class ISPCTarget(CFamilyTarget): """A code generation target for Intel's `ISPC `_ SPMD programming language, to target Intel's Knight's hardware and modern Intel CPUs with wide vector units. @@ -200,7 +200,7 @@ class ISPCTarget(CTarget): # }}} -class ISPCASTBuilder(CASTBuilder): +class ISPCASTBuilder(CFamilyASTBuilder): def _arg_names_and_decls(self, codegen_state): implemented_data_info = codegen_state.implemented_data_info arg_names = [iai.name for iai in implemented_data_info] diff --git a/loopy/target/opencl.py b/loopy/target/opencl.py index 8a6e52842..04d436043 100644 --- a/loopy/target/opencl.py +++ b/loopy/target/opencl.py @@ -26,7 +26,7 @@ THE SOFTWARE. import numpy as np -from loopy.target.c import CTarget, CASTBuilder +from loopy.target.c import CFamilyTarget, CFamilyASTBuilder from loopy.target.c.codegen.expression import ExpressionToCExpressionMapper from pytools import memoize_method from loopy.diagnostic import LoopyError @@ -304,7 +304,7 @@ class ExpressionToOpenCLCExpressionMapper(ExpressionToCExpressionMapper): # {{{ target -class OpenCLTarget(CTarget): +class OpenCLTarget(CFamilyTarget): """A target for the OpenCL C heterogeneous compute programming language. """ @@ -362,7 +362,7 @@ class OpenCLTarget(CTarget): # {{{ ast builder -class OpenCLCASTBuilder(CASTBuilder): +class OpenCLCASTBuilder(CFamilyASTBuilder): # {{{ library def function_manglers(self): -- GitLab From df614ccb48ed6c3c8058220dac12d8e5f55daeaa Mon Sep 17 00:00:00 2001 From: Kaushik Kulkarni Date: Tue, 22 Oct 2019 22:05:50 -0500 Subject: [PATCH 4/5] minor typo --- loopy/target/c/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py index 1b7ca0826..e39536fdd 100644 --- a/loopy/target/c/__init__.py +++ b/loopy/target/c/__init__.py @@ -1081,7 +1081,7 @@ class CTarget(CFamilyTarget): class CASTBuilder(CFamilyASTBuilder): def preamble_generators(self): return ( - super(CFamilyASTBuilder, self).preamble_generators() + [ + super(CASTBuilder, self).preamble_generators() + [ c99_preamble_generator, ]) -- GitLab From f023b8673e60325bd4e12fe4883b2bf4ef55c5c0 Mon Sep 17 00:00:00 2001 From: "[6~" Date: Wed, 23 Oct 2019 11:44:03 -0500 Subject: [PATCH 5/5] Naming and doc fixes for C99 target/int types --- loopy/target/c/__init__.py | 15 +++++++++++---- loopy/target/c/compyte | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py index e39536fdd..6e3602eda 100644 --- a/loopy/target/c/__init__.py +++ b/loopy/target/c/__init__.py @@ -79,7 +79,7 @@ class DTypeRegistryWrapper(object): def c99_preamble_generator(preamble_info): if any(dtype.is_integral() for dtype in preamble_info.seen_dtypes): - yield("10_inttypes", "#include ") + yield("10_stdint", "#include ") def _preamble_generator(preamble_info): @@ -320,7 +320,9 @@ class CExpression(object): class CFamilyTarget(TargetBase): - """A target for plain "C", without any parallel extensions. + """A target for "least-common denominator C", without any parallel + extensions, and without use of any C99 specifics. Intended to be + usable as a common base for C99, C++, OpenCL, CUDA, and the like. """ hash_fields = TargetBase.hash_fields + ("fortran_abi",) @@ -1066,15 +1068,20 @@ def generate_header(kernel, codegen_result=None): # {{{ C99 target class CTarget(CFamilyTarget): + """This target may emit code using all features of C99. + For a target base supporting "least-common-denominator" C, + see :class:`CFamilyTarget`. + """ + def get_device_ast_builder(self): return CASTBuilder(self) @memoize_method def get_dtype_registry(self): from loopy.target.c.compyte.dtypes import ( - DTypeRegistry, fill_registry_with_c_inttypes_types) + DTypeRegistry, fill_registry_with_c99_stdint_types) result = DTypeRegistry() - fill_registry_with_c_inttypes_types(result) + fill_registry_with_c99_stdint_types(result) return DTypeRegistryWrapper(result) diff --git a/loopy/target/c/compyte b/loopy/target/c/compyte index 04eb2fc75..25ee8b48f 160000 --- a/loopy/target/c/compyte +++ b/loopy/target/c/compyte @@ -1 +1 @@ -Subproject commit 04eb2fc75235593ddc609628cfb5ec1f9d9aa393 +Subproject commit 25ee8b48fd0c7d9f0bd987c6862cdb1884fb1372 -- GitLab