diff --git a/.dict_custom.txt b/.dict_custom.txt index 2e5398c733..d9518786a2 100644 --- a/.dict_custom.txt +++ b/.dict_custom.txt @@ -108,6 +108,7 @@ Valgrind variadic subclasses oneAPI +Cuda getter setter bitwise diff --git a/.github/actions/pytest_parallel/action.yml b/.github/actions/pytest_parallel/action.yml index c7c77d99c7..f91d84915b 100644 --- a/.github/actions/pytest_parallel/action.yml +++ b/.github/actions/pytest_parallel/action.yml @@ -10,8 +10,8 @@ runs: steps: - name: Test with pytest run: | - mpiexec -n 4 ${MPI_OPTS} python -m pytest epyccel/test_parallel_epyccel.py -v -m parallel -rXx - #mpiexec -n 4 ${MPI_OPTS} python -m pytest epyccel -v -m parallel -rXx + mpiexec -n 4 ${MPI_OPTS} python -m pytest epyccel/test_parallel_epyccel.py -v -m "parallel and not cuda" -rXx + #mpiexec -n 4 ${MPI_OPTS} python -m pytest epyccel -v -m "parallel and not cuda" -rXx shell: ${{ inputs.shell_cmd }} working-directory: ./tests diff --git a/.github/actions/pytest_run/action.yml b/.github/actions/pytest_run/action.yml index 12f75166cf..c2849e011c 100644 --- a/.github/actions/pytest_run/action.yml +++ b/.github/actions/pytest_run/action.yml @@ -51,13 +51,13 @@ runs: working-directory: ./tests id: pytest_3 - name: Test Fortran translations - run: python -m pytest -n auto -rX ${FLAGS} -m "not (parallel or xdist_incompatible) and not (c or python or ccuda) ${{ inputs.pytest_mark }}" --ignore=symbolic --ignore=ndarrays 2>&1 | tee s4_outfile.out + run: python -m pytest -n auto -rX ${FLAGS} -m "not (parallel or xdist_incompatible) and not (c or python or cuda) ${{ inputs.pytest_mark }}" --ignore=symbolic --ignore=ndarrays 2>&1 | tee s4_outfile.out shell: ${{ inputs.shell_cmd }} working-directory: ./tests id: pytest_4 - name: Test multi-file Fortran translations run: | - python -m pytest -rX ${FLAGS} -m "xdist_incompatible and not parallel and not (c or python or ccuda) ${{ inputs.pytest_mark }}" --ignore=symbolic --ignore=ndarrays 2>&1 | tee s5_outfile.out + python -m pytest -rX ${FLAGS} -m "xdist_incompatible and not parallel and not (c or python or cuda) ${{ inputs.pytest_mark }}" --ignore=symbolic --ignore=ndarrays 2>&1 | tee s5_outfile.out pyccel-clean shell: ${{ inputs.shell_cmd }} working-directory: ./tests diff --git a/.github/actions/pytest_run_cuda/action.yml b/.github/actions/pytest_run_cuda/action.yml index 52092a6e02..46f90552ed 100644 --- a/.github/actions/pytest_run_cuda/action.yml +++ b/.github/actions/pytest_run_cuda/action.yml @@ -1,4 +1,4 @@ -name: 'Pyccel pytest commands generating Ccuda' +name: 'Pyccel pytest commands generating Cuda' inputs: shell_cmd: description: 'Specifies the shell command (different for anaconda)' @@ -11,7 +11,14 @@ runs: - name: Ccuda tests with pytest run: | # Catch exit 5 (no tests found) - sh -c 'python -m pytest -n auto -rx -m "not (parallel or xdist_incompatible) and ccuda" --ignore=symbolic --ignore=ndarrays; ret=$?; [ $ret = 5 ] && exit 0 || exit $ret' + python -m pytest -rX ${FLAGS} -m "not (xdist_incompatible or parallel) and cuda ${{ inputs.pytest_mark }}" --ignore=symbolic --ignore=ndarrays 2>&1 | tee s1_outfile.out pyccel-clean shell: ${{ inputs.shell_cmd }} working-directory: ./tests + - name: Final step + if: always() + id: status + run: + python ci_tools/json_pytest_output.py -t "Cuda Test Summary" --tests "Cuda tests:${{ steps.pytest_1.outcome }}:tests/s1_outfile.out" + + shell: ${{ inputs.shell_cmd }} diff --git a/CHANGELOG.md b/CHANGELOG.md index d0962522b0..d33fcc6141 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ # Change Log All notable changes to this project will be documented in this file. +## \[Cuda - UNRELEASED\] + +### Added + +- #32 : add support for `nvcc` Compiler and `cuda` language as a possible option. + ## \[UNRELEASED\] ### Added diff --git a/pyccel/codegen/codegen.py b/pyccel/codegen/codegen.py index 3da73d1ff9..58a8c84de5 100644 --- a/pyccel/codegen/codegen.py +++ b/pyccel/codegen/codegen.py @@ -9,16 +9,18 @@ from pyccel.codegen.printing.fcode import FCodePrinter from pyccel.codegen.printing.ccode import CCodePrinter from pyccel.codegen.printing.pycode import PythonCodePrinter +from pyccel.codegen.printing.cucode import CudaCodePrinter from pyccel.ast.core import FunctionDef, Interface, ModuleHeader from pyccel.utilities.stage import PyccelStage -_extension_registry = {'fortran': 'f90', 'c':'c', 'python':'py'} -_header_extension_registry = {'fortran': None, 'c':'h', 'python':None} +_extension_registry = {'fortran': 'f90', 'c':'c', 'python':'py', 'cuda':'cu'} +_header_extension_registry = {'fortran': None, 'c':'h', 'python':None, 'cuda':'h'} printer_registry = { 'fortran':FCodePrinter, 'c':CCodePrinter, - 'python':PythonCodePrinter + 'python':PythonCodePrinter, + 'cuda':CudaCodePrinter } pyccel_stage = PyccelStage() diff --git a/pyccel/codegen/compiling/compilers.py b/pyccel/codegen/compiling/compilers.py index feafa4bea8..48e225cb83 100644 --- a/pyccel/codegen/compiling/compilers.py +++ b/pyccel/codegen/compiling/compilers.py @@ -441,7 +441,10 @@ def compile_shared_library(self, compile_obj, output_folder, verbose = False, sh # Collect compile information exec_cmd, includes, libs_flags, libdirs_flags, m_code = \ self._get_compile_components(compile_obj, accelerators) - linker_libdirs_flags = ['-Wl,-rpath' if l == '-L' else l for l in libdirs_flags] + if self._info['exec'] == 'nvcc': + linker_libdirs_flags = ['-Xcompiler' if l == '-L' else f'"-Wl,-rpath,{l}"' for l in libdirs_flags] + else: + linker_libdirs_flags = ['-Wl,-rpath' if l == '-L' else l for l in libdirs_flags] flags.insert(0,"-shared") diff --git a/pyccel/codegen/pipeline.py b/pyccel/codegen/pipeline.py index 648e8ca628..daa20af78c 100644 --- a/pyccel/codegen/pipeline.py +++ b/pyccel/codegen/pipeline.py @@ -179,9 +179,10 @@ def handle_error(stage): if language is None: language = 'fortran' - # Choose Fortran compiler + # Choose Default compiler if compiler is None: - compiler = os.environ.get('PYCCEL_DEFAULT_COMPILER', 'GNU') + default_compiler_family = 'nvidia' if language == 'cuda' else 'GNU' + compiler = os.environ.get('PYCCEL_DEFAULT_COMPILER', default_compiler_family) fflags = [] if fflags is None else fflags.split() wrapper_flags = [] if wrapper_flags is None else wrapper_flags.split() diff --git a/pyccel/codegen/printing/cucode.py b/pyccel/codegen/printing/cucode.py new file mode 100644 index 0000000000..e70b57bc20 --- /dev/null +++ b/pyccel/codegen/printing/cucode.py @@ -0,0 +1,74 @@ +# coding: utf-8 +#------------------------------------------------------------------------------------------# +# This file is part of Pyccel which is released under MIT License. See the LICENSE file or # +# go to https://github.com/pyccel/pyccel/blob/master/LICENSE for full license details. # +#------------------------------------------------------------------------------------------# +""" +Provide tools for generating and handling CUDA code. +This module is designed to interface Pyccel's Abstract Syntax Tree (AST) with CUDA, +enabling the direct translation of high-level Pyccel expressions into CUDA code. +""" + +from pyccel.codegen.printing.ccode import CCodePrinter, c_library_headers + +from pyccel.ast.core import Import, Module + +from pyccel.errors.errors import Errors + + +errors = Errors() + +__all__ = ["CudaCodePrinter"] + +class CudaCodePrinter(CCodePrinter): + """ + Print code in CUDA format. + + This printer converts Pyccel's Abstract Syntax Tree (AST) into strings of CUDA code. + Navigation through this file utilizes _print_X functions, + as is common with all printers. + + Parameters + ---------- + filename : str + The name of the file being pyccelised. + prefix_module : str + A prefix to be added to the name of the module. + """ + language = "cuda" + + def __init__(self, filename, prefix_module = None): + + errors.set_target(filename, 'file') + + super().__init__(filename) + + def _print_Module(self, expr): + self.set_scope(expr.scope) + self._current_module = expr.name + body = ''.join(self._print(i) for i in expr.body) + + global_variables = ''.join(self._print(d) for d in expr.declarations) + + # Print imports last to be sure that all additional_imports have been collected + imports = [Import(expr.name, Module(expr.name,(),())), *self._additional_imports.values()] + c_headers_imports = '' + local_imports = '' + + for imp in imports: + if imp.source in c_library_headers: + c_headers_imports += self._print(imp) + else: + local_imports += self._print(imp) + + imports = f'{c_headers_imports}\ + extern "C"{{\n\ + {local_imports}\ + }}' + + code = f'{imports}\n\ + {global_variables}\n\ + {body}\n' + + self.exit_scope() + return code diff --git a/pyccel/commands/console.py b/pyccel/commands/console.py index 60eaab0d70..01827eb5c9 100644 --- a/pyccel/commands/console.py +++ b/pyccel/commands/console.py @@ -80,7 +80,7 @@ def pyccel(files=None, mpi=None, openmp=None, openacc=None, output_dir=None, com # ... backend compiler options group = parser.add_argument_group('Backend compiler options') - group.add_argument('--language', choices=('fortran', 'c', 'python'), help='Generated language') + group.add_argument('--language', choices=('fortran', 'c', 'python', 'cuda'), help='Generated language') group.add_argument('--compiler', help='Compiler family or json file containing a compiler description {GNU,intel,PGI}') diff --git a/pyccel/compilers/default_compilers.py b/pyccel/compilers/default_compilers.py index 166085d22e..d47856773c 100644 --- a/pyccel/compilers/default_compilers.py +++ b/pyccel/compilers/default_compilers.py @@ -185,6 +185,15 @@ }, 'family': 'nvidia', } +#------------------------------------------------------------ +nvcc_info = {'exec' : 'nvcc', + 'language' : 'cuda', + 'debug_flags' : ("-g",), + 'release_flags': ("-O3",), + 'general_flags': ('--compiler-options', '-fPIC',), + 'family' : 'nvidia' + } + #------------------------------------------------------------ def change_to_lib_flag(lib): @@ -288,6 +297,7 @@ def change_to_lib_flag(lib): pgfortran_info.update(python_info) nvc_info.update(python_info) nvfort_info.update(python_info) +nvcc_info.update(python_info) available_compilers = {('GNU', 'c') : gcc_info, ('GNU', 'fortran') : gfort_info, @@ -296,6 +306,7 @@ def change_to_lib_flag(lib): ('PGI', 'c') : pgcc_info, ('PGI', 'fortran') : pgfortran_info, ('nvidia', 'c') : nvc_info, - ('nvidia', 'fortran') : nvfort_info} + ('nvidia', 'fortran') : nvfort_info, + ('nvidia', 'cuda'): nvcc_info} vendors = ('GNU','intel','PGI','nvidia') diff --git a/pyccel/naming/__init__.py b/pyccel/naming/__init__.py index a71d841c8e..1b8514703b 100644 --- a/pyccel/naming/__init__.py +++ b/pyccel/naming/__init__.py @@ -10,7 +10,9 @@ from .fortrannameclashchecker import FortranNameClashChecker from .cnameclashchecker import CNameClashChecker from .pythonnameclashchecker import PythonNameClashChecker +from .cudanameclashchecker import CudaNameClashChecker name_clash_checkers = {'fortran':FortranNameClashChecker(), 'c':CNameClashChecker(), - 'python':PythonNameClashChecker()} + 'python':PythonNameClashChecker(), + 'cuda':CudaNameClashChecker()} diff --git a/pyccel/naming/cudanameclashchecker.py b/pyccel/naming/cudanameclashchecker.py new file mode 100644 index 0000000000..971204e912 --- /dev/null +++ b/pyccel/naming/cudanameclashchecker.py @@ -0,0 +1,92 @@ +# coding: utf-8 +#------------------------------------------------------------------------------------------# +# This file is part of Pyccel which is released under MIT License. See the LICENSE file or # +# go to https://github.com/pyccel/pyccel/blob/master/LICENSE for full license details. # +#------------------------------------------------------------------------------------------# +""" +Handles name clash problems in Cuda +""" +from .languagenameclashchecker import LanguageNameClashChecker + +class CudaNameClashChecker(LanguageNameClashChecker): + """ + Class containing functions to help avoid problematic names in Cuda. + + A class which provides functionalities to check or propose variable names and + verify that they do not cause name clashes. Name clashes may be due to + new variables, or due to the use of reserved keywords. + """ + # Keywords as mentioned on https://en.cppreference.com/w/c/keyword + keywords = set(['isign', 'fsign', 'csign', 'auto', 'break', 'case', 'char', 'const', + 'continue', 'default', 'do', 'double', 'else', 'enum', + 'extern', 'float', 'for', 'goto', 'if', 'inline', 'int', + 'long', 'register', 'restrict', 'return', 'short', 'signed', + 'sizeof', 'static', 'struct', 'switch', 'typedef', 'union', + 'unsigned', 'void', 'volatile', 'whie', '_Alignas', + '_Alignof', '_Atomic', '_Bool', '_Complex', 'Decimal128', + '_Decimal32', '_Decimal64', '_Generic', '_Imaginary', + '_Noreturn', '_Static_assert', '_Thread_local', 't_ndarray', + 'array_create', 'new_slice', 'array_slicing', 'alias_assign', + 'transpose_alias_assign', 'array_fill', 't_slice', + 'GET_INDEX_EXP1', 'GET_INDEX_EXP2', 'GET_INDEX_EXP2', + 'GET_INDEX_EXP3', 'GET_INDEX_EXP4', 'GET_INDEX_EXP5', + 'GET_INDEX_EXP6', 'GET_INDEX_EXP7', 'GET_INDEX_EXP8', + 'GET_INDEX_EXP9', 'GET_INDEX_EXP10', 'GET_INDEX_EXP11', + 'GET_INDEX_EXP12', 'GET_INDEX_EXP13', 'GET_INDEX_EXP14', + 'GET_INDEX_EXP15', 'NUM_ARGS_H1', 'NUM_ARGS', + 'GET_INDEX_FUNC_H2', 'GET_INDEX_FUNC', 'GET_INDEX', + 'INDEX', 'GET_ELEMENT', 'free_array', 'free_pointer', + 'get_index', 'numpy_to_ndarray_strides', + 'numpy_to_ndarray_shape', 'get_size', 'order_f', 'order_c', 'array_copy_data']) + + def has_clash(self, name, symbols): + """ + Indicate whether the proposed name causes any clashes. + + Checks if a suggested name conflicts with predefined + keywords or specified symbols,returning true for a clash. + This method is crucial for maintaining namespace integrity and + preventing naming conflicts in code generation processes. + + Parameters + ---------- + name : str + The suggested name. + symbols : set + Symbols which should be considered as collisions. + + Returns + ------- + bool + True if the name is a collision. + False if the name is collision free. + """ + return any(name == k for k in self.keywords) or \ + any(name == s for s in symbols) + + def get_collisionless_name(self, name, symbols): + """ + Get a valid name which doesn't collision with symbols or Cuda keywords. + + Find a new name based on the suggested name which will not cause + conflicts with Cuda keywords, does not appear in the provided symbols, + and is a valid name in Cuda code. + + Parameters + ---------- + name : str + The suggested name. + symbols : set + Symbols which should be considered as collisions. + + Returns + ------- + str + A new name which is collision free. + """ + if len(name)>4 and all(name[i] == '_' for i in (0,1,-1,-2)): + # Ignore magic methods + return name + if name[0] == '_': + name = 'private'+name + return self._get_collisionless_name(name, symbols) diff --git a/pyccel/stdlib/numpy/numpy_c.c b/pyccel/stdlib/numpy/numpy_c.c index 36e4a205ec..1b5a1bf017 100644 --- a/pyccel/stdlib/numpy/numpy_c.c +++ b/pyccel/stdlib/numpy/numpy_c.c @@ -17,8 +17,10 @@ double fsign(double x) return SIGN(x); } +#ifndef __NVCC__ /* numpy.sign for complex */ double complex csign(double complex x) { return x ? ((!creal(x) && cimag(x) < 0) || (creal(x) < 0) ? -1 : 1) : 0; } +#endif diff --git a/pyccel/stdlib/numpy/numpy_c.h b/pyccel/stdlib/numpy/numpy_c.h index 4133e9dbe9..326ec3a549 100644 --- a/pyccel/stdlib/numpy/numpy_c.h +++ b/pyccel/stdlib/numpy/numpy_c.h @@ -15,6 +15,8 @@ long long int isign(long long int x); double fsign(double x); +#ifndef __NVCC__ double complex csign(double complex x); +#endif #endif diff --git a/pytest.ini b/pytest.ini index 42eb0d72ba..3792ab65f9 100644 --- a/pytest.ini +++ b/pytest.ini @@ -9,3 +9,4 @@ markers = python: test to generate python code xdist_incompatible: test which compiles a file also compiled by another test external: test using an external dll (problematic with conda on Windows) + cuda: test to generate cuda code diff --git a/tests/conftest.py b/tests/conftest.py index 79144b6978..a5082ef6e8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -21,6 +21,17 @@ def language(request): return request.param +@pytest.fixture( params=[ + pytest.param("fortran", marks = pytest.mark.fortran), + pytest.param("c", marks = pytest.mark.c), + pytest.param("python", marks = pytest.mark.python), + pytest.param("cuda", marks = pytest.mark.cuda) + ], + scope = "session" +) +def language_with_cuda(request): + return request.param + def move_coverage(path_dir): for root, _, files in os.walk(path_dir): for name in files: diff --git a/tests/epyccel/test_base.py b/tests/epyccel/test_base.py index c22064d321..413f79eef1 100644 --- a/tests/epyccel/test_base.py +++ b/tests/epyccel/test_base.py @@ -7,128 +7,128 @@ from utilities import epyccel_test -def test_is_false(language): - test = epyccel_test(base.is_false, lang=language) +def test_is_false(language_with_cuda): + test = epyccel_test(base.is_false, lang=language_with_cuda) test.compare_epyccel( True ) test.compare_epyccel( False ) -def test_is_true(language): - test = epyccel_test(base.is_true, lang=language) +def test_is_true(language_with_cuda): + test = epyccel_test(base.is_true, lang=language_with_cuda) test.compare_epyccel( True ) test.compare_epyccel( False ) -def test_compare_is(language): - test = epyccel_test(base.compare_is, lang=language) +def test_compare_is(language_with_cuda): + test = epyccel_test(base.compare_is, lang=language_with_cuda) test.compare_epyccel( True, True ) test.compare_epyccel( True, False ) test.compare_epyccel( False, True ) test.compare_epyccel( False, False ) -def test_compare_is_not(language): - test = epyccel_test(base.compare_is_not, lang=language) +def test_compare_is_not(language_with_cuda): + test = epyccel_test(base.compare_is_not, lang=language_with_cuda) test.compare_epyccel( True, True ) test.compare_epyccel( True, False ) test.compare_epyccel( False, True ) test.compare_epyccel( False, False ) -def test_compare_is_int(language): - test = epyccel_test(base.compare_is_int, lang=language) +def test_compare_is_int(language_with_cuda): + test = epyccel_test(base.compare_is_int, lang=language_with_cuda) test.compare_epyccel( True, 1 ) test.compare_epyccel( True, 0 ) test.compare_epyccel( False, 1 ) test.compare_epyccel( False, 0 ) -def test_compare_is_not_int(language): - test = epyccel_test(base.compare_is_not_int, lang=language) +def test_compare_is_not_int(language_with_cuda): + test = epyccel_test(base.compare_is_not_int, lang=language_with_cuda) test.compare_epyccel( True, 1 ) test.compare_epyccel( True, 0 ) test.compare_epyccel( False, 1 ) test.compare_epyccel( False, 0 ) -def test_not_false(language): - test = epyccel_test(base.not_false, lang=language) +def test_not_false(language_with_cuda): + test = epyccel_test(base.not_false, lang=language_with_cuda) test.compare_epyccel( True ) test.compare_epyccel( False ) -def test_not_true(language): - test = epyccel_test(base.not_true, lang=language) +def test_not_true(language_with_cuda): + test = epyccel_test(base.not_true, lang=language_with_cuda) test.compare_epyccel( True ) test.compare_epyccel( False ) -def test_eq_false(language): - test = epyccel_test(base.eq_false, lang=language) +def test_eq_false(language_with_cuda): + test = epyccel_test(base.eq_false, lang=language_with_cuda) test.compare_epyccel( True ) test.compare_epyccel( False ) -def test_eq_true(language): - test = epyccel_test(base.eq_true, lang=language) +def test_eq_true(language_with_cuda): + test = epyccel_test(base.eq_true, lang=language_with_cuda) test.compare_epyccel( True ) test.compare_epyccel( False ) -def test_neq_false(language): - test = epyccel_test(base.eq_false, lang=language) +def test_neq_false(language_with_cuda): + test = epyccel_test(base.eq_false, lang=language_with_cuda) test.compare_epyccel( True ) test.compare_epyccel( False ) -def test_neq_true(language): - test = epyccel_test(base.eq_true, lang=language) +def test_neq_true(language_with_cuda): + test = epyccel_test(base.eq_true, lang=language_with_cuda) test.compare_epyccel( True ) test.compare_epyccel( False ) -def test_not(language): - test = epyccel_test(base.not_val, lang=language) +def test_not(language_with_cuda): + test = epyccel_test(base.not_val, lang=language_with_cuda) test.compare_epyccel( True ) test.compare_epyccel( False ) -def test_not_int(language): - test = epyccel_test(base.not_int, lang=language) +def test_not_int(language_with_cuda): + test = epyccel_test(base.not_int, lang=language_with_cuda) test.compare_epyccel( 0 ) test.compare_epyccel( 4 ) -def test_compare_is_nil(language): - test = epyccel_test(base.is_nil, lang=language) +def test_compare_is_nil(language_with_cuda): + test = epyccel_test(base.is_nil, lang=language_with_cuda) test.compare_epyccel( None ) -def test_compare_is_not_nil(language): - test = epyccel_test(base.is_not_nil, lang=language) +def test_compare_is_not_nil(language_with_cuda): + test = epyccel_test(base.is_not_nil, lang=language_with_cuda) test.compare_epyccel( None ) -def test_cast_int(language): - test = epyccel_test(base.cast_int, lang=language) +def test_cast_int(language_with_cuda): + test = epyccel_test(base.cast_int, lang=language_with_cuda) test.compare_epyccel( 4 ) - test = epyccel_test(base.cast_float_to_int, lang=language) + test = epyccel_test(base.cast_float_to_int, lang=language_with_cuda) test.compare_epyccel( 4.5 ) -def test_cast_bool(language): - test = epyccel_test(base.cast_bool, lang=language) +def test_cast_bool(language_with_cuda): + test = epyccel_test(base.cast_bool, lang=language_with_cuda) test.compare_epyccel( True ) -def test_cast_float(language): - test = epyccel_test(base.cast_float, lang=language) +def test_cast_float(language_with_cuda): + test = epyccel_test(base.cast_float, lang=language_with_cuda) test.compare_epyccel( 4.5 ) - test = epyccel_test(base.cast_int_to_float, lang=language) + test = epyccel_test(base.cast_int_to_float, lang=language_with_cuda) test.compare_epyccel( 4 ) -def test_if_0_int(language): - test = epyccel_test(base.if_0_int, lang=language) +def test_if_0_int(language_with_cuda): + test = epyccel_test(base.if_0_int, lang=language_with_cuda) test.compare_epyccel( 22 ) test.compare_epyccel( 0 ) -def test_if_0_real(language): - test = epyccel_test(base.if_0_real, lang=language) +def test_if_0_real(language_with_cuda): + test = epyccel_test(base.if_0_real, lang=language_with_cuda) test.compare_epyccel( 22.3 ) test.compare_epyccel( 0.0 ) -def test_same_int(language): - test = epyccel_test(base.is_same_int, lang=language) +def test_same_int(language_with_cuda): + test = epyccel_test(base.is_same_int, lang=language_with_cuda) test.compare_epyccel( 22 ) - test = epyccel_test(base.isnot_same_int, lang=language) + test = epyccel_test(base.isnot_same_int, lang=language_with_cuda) test.compare_epyccel( 22 ) -def test_same_float(language): - test = epyccel_test(base.is_same_float, lang=language) +def test_same_float(language_with_cuda): + test = epyccel_test(base.is_same_float, lang=language_with_cuda) test.compare_epyccel( 22.2 ) - test = epyccel_test(base.isnot_same_float, lang=language) + test = epyccel_test(base.isnot_same_float, lang=language_with_cuda) test.compare_epyccel( 22.2 ) @pytest.mark.parametrize( 'language', [ @@ -150,28 +150,28 @@ def test_same_complex(language): test = epyccel_test(base.isnot_same_complex, lang=language) test.compare_epyccel( complex(2,3) ) -def test_is_types(language): - test = epyccel_test(base.is_types, lang=language) +def test_is_types(language_with_cuda): + test = epyccel_test(base.is_types, lang=language_with_cuda) test.compare_epyccel( 1, 1.0 ) -def test_isnot_types(language): - test = epyccel_test(base.isnot_types, lang=language) +def test_isnot_types(language_with_cuda): + test = epyccel_test(base.isnot_types, lang=language_with_cuda) test.compare_epyccel( 1, 1.0 ) -def test_none_is_none(language): - test = epyccel_test(base.none_is_none, lang=language) +def test_none_is_none(language_with_cuda): + test = epyccel_test(base.none_is_none, lang=language_with_cuda) test.compare_epyccel() -def test_none_isnot_none(language): - test = epyccel_test(base.none_isnot_none, lang=language) +def test_none_isnot_none(language_with_cuda): + test = epyccel_test(base.none_isnot_none, lang=language_with_cuda) test.compare_epyccel() -def test_pass_if(language): - test = epyccel_test(base.pass_if, lang=language) +def test_pass_if(language_with_cuda): + test = epyccel_test(base.pass_if, lang=language_with_cuda) test.compare_epyccel(2) -def test_pass2_if(language): - test = epyccel_test(base.pass2_if, lang=language) +def test_pass2_if(language_with_cuda): + test = epyccel_test(base.pass2_if, lang=language_with_cuda) test.compare_epyccel(0.2) test.compare_epyccel(0.0) @@ -192,15 +192,15 @@ def test_use_optional(language): test.compare_epyccel() test.compare_epyccel(6) -def test_none_equality(language): - test = epyccel_test(base.none_equality, lang=language) +def test_none_equality(language_with_cuda): + test = epyccel_test(base.none_equality, lang=language_with_cuda) test.compare_epyccel() test.compare_epyccel(6) -def test_none_none_equality(language): - test = epyccel_test(base.none_none_equality, lang=language) +def test_none_none_equality(language_with_cuda): + test = epyccel_test(base.none_none_equality, lang=language_with_cuda) test.compare_epyccel() -def test_none_literal_equality(language): - test = epyccel_test(base.none_literal_equality, lang=language) +def test_none_literal_equality(language_with_cuda): + test = epyccel_test(base.none_literal_equality, lang=language_with_cuda) test.compare_epyccel()