def test_stencil_information(tmpdir): '''Test that the GOStencil class provides the expected stencil information. This exercises the "pointwise" name and the stencil description ''' _, invoke_info = parse(os.path.join(BASE_PATH, "test28_invoke_kernel_stencil.f90"), api=API) psy = PSyFactory(API).create(invoke_info) invoke = psy.invokes.invoke_list[0] schedule = invoke.schedule kernel = schedule.coded_kernels()[0] # args 1 and 3 specify pointwise as a stencil access for idx in [0, 2]: pointwise_arg = kernel.args[idx] assert pointwise_arg.stencil assert not pointwise_arg.stencil.has_stencil assert pointwise_arg.stencil.name == "go_pointwise" # Check that a pointwise access patterns returns # a depth of (000, 010, 000) for j in [-1, 0, 1]: for i in [-1, 0, 1]: if i == 0 and j == 0: assert pointwise_arg.stencil.depth(i, j) == 1 else: assert pointwise_arg.stencil.depth(i, j) == 0 # arg 4 provides grid information so knows nothing about stencils grid_arg = kernel.args[3] with pytest.raises(AttributeError) as excinfo: _ = grid_arg.stencil assert "object has no attribute 'stencil'" in str(excinfo.value) # arg 2 has a stencil stencil_arg = kernel.args[1] assert stencil_arg.stencil.has_stencil for idx2 in range(-1, 2): for idx1 in range(-1, 2): if idx1 in [0, 1] and idx2 == 0: expected_depth = 1 else: expected_depth = 0 assert stencil_arg.stencil.depth(idx1, idx2) == expected_depth assert GOcean1p0Build(tmpdir).code_compiles(psy)
def test_new_kernel_file(kernel_outputdir, monkeypatch): ''' Check that we write out the transformed kernel to the CWD. ''' from fparser.two import Fortran2003, parser from fparser.common.readfortran import FortranFileReader # Ensure kernel-output directory is uninitialised config = Config.get() monkeypatch.setattr(config, "_kernel_naming", "multiple") psy, invoke = get_invoke("nemolite2d_alg_mod.f90", api="gocean1.0", idx=0) sched = invoke.schedule kern = sched.coded_kernels()[0] rtrans = ACCRoutineTrans() _, _ = rtrans.apply(kern) # Generate the code (this triggers the generation of a new kernel) code = str(psy.gen).lower() # Work out the value of the tag used to re-name the kernel tag = re.search('use continuity(.+?)_mod', code).group(1) assert ("use continuity{0}_mod, only: continuity{0}_code".format(tag) in code) assert "call continuity{0}_code(".format(tag) in code # The kernel and module name should have gained the tag just identified # and be written to the CWD filename = os.path.join(str(kernel_outputdir), "continuity{0}_mod.f90".format(tag)) assert os.path.isfile(filename) # Parse the new kernel file f2003_parser = parser.ParserFactory().create() reader = FortranFileReader(filename) prog = f2003_parser(reader) # Check that the module has the right name modules = walk(prog.content, Fortran2003.Module_Stmt) assert str(modules[0].items[1]) == "continuity{0}_mod".format(tag) # Check that the subroutine has the right name subs = walk(prog.content, Fortran2003.Subroutine_Stmt) found = False for sub in subs: if str(sub.items[1]) == "continuity{0}_code".format(tag): found = True break assert found from psyclone.tests.gocean1p0_build import GOcean1p0Build # If compilation fails this will raise an exception GOcean1p0Build(kernel_outputdir).compile_file(filename)
def infra_compile(tmpdir_factory, request): '''A per-session initialisation function that sets the compilation flags in the Compile class based on command line options for --compile, --compileopencl, --f90, --f90flags. Then makes sure that the infrastructure files for the dynamo0p3 and gocean1p0 APIs are compiled (if compilation was enabled). ''' Compile.store_compilation_flags(request.config) # Create a temporary directory to store the compiled files. # Note that this directory is unique even if compiled in # parallel, i.e. each process has its own copy of the # compiled infrastructure file, which avoids the problem # of synchronisation between the processes. tmpdir = tmpdir_factory.mktemp('dynamo_wrapper') # This is the first instance created. This will trigger # compilation of the infrastructure files. LFRicBuild(tmpdir) tmpdir = tmpdir_factory.mktemp('dl_esm_inf') GOcean1p0Build(tmpdir)
def test_new_kernel_file(kernel_outputdir, monkeypatch, fortran_reader): ''' Check that we write out the transformed kernel to the CWD. ''' # Ensure kernel-output directory is uninitialised config = Config.get() monkeypatch.setattr(config, "_kernel_naming", "multiple") psy, invoke = get_invoke("nemolite2d_alg_mod.f90", api="gocean1.0", idx=0) sched = invoke.schedule kern = sched.coded_kernels()[0] rtrans = ACCRoutineTrans() _, _ = rtrans.apply(kern) # Generate the code (this triggers the generation of a new kernel) code = str(psy.gen).lower() # Work out the value of the tag used to re-name the kernel tag = re.search('use continuity(.+?)_mod', code).group(1) assert ("use continuity{0}_mod, only: continuity{0}_code".format(tag) in code) assert "call continuity{0}_code(".format(tag) in code # The kernel and module name should have gained the tag just identified # and be written to the CWD filename = os.path.join(str(kernel_outputdir), "continuity{0}_mod.f90".format(tag)) assert os.path.isfile(filename) # Parse the new kernel file psyir = fortran_reader.psyir_from_file(filename) # Check that the module has the right name assert isinstance(psyir, FileContainer) module = psyir.children[0] assert module.name == "continuity{0}_mod".format(tag) # Check that the subroutine has the right name found = False for sub in psyir.walk(Routine): if sub.name == "continuity{0}_code".format(tag): found = True break assert found from psyclone.tests.gocean1p0_build import GOcean1p0Build # If compilation fails this will raise an exception GOcean1p0Build(kernel_outputdir).compile_file(filename)