def test_psy_init(kernel_outputdir): ''' Check that we create a psy_init() routine that sets-up the OpenCL environment. ''' psy, _ = get_invoke("single_invoke.f90", API, idx=0) sched = psy.invokes.invoke_list[0].schedule otrans = OCLTrans() otrans.apply(sched) generated_code = str(psy.gen) expected = ( " SUBROUTINE psy_init()\n" " USE fortcl, ONLY: ocl_env_init, add_kernels\n" " CHARACTER(LEN=30) kernel_names(1)\n" " LOGICAL, save :: initialised=.False.\n" " ! Check to make sure we only execute this routine once\n" " IF (.not. initialised) THEN\n" " initialised = .True.\n" " ! Initialise the OpenCL environment/device\n" " CALL ocl_env_init\n" " ! The kernels this PSy layer module requires\n" " kernel_names(1) = \"compute_cu_code\"\n" " ! Create the OpenCL kernel objects. Expects to find all of " "the compiled\n" " ! kernels in PSYCLONE_KERNELS_FILE.\n" " CALL add_kernels(1, kernel_names)\n" " END IF \n" " END SUBROUTINE psy_init\n") assert expected in generated_code assert GOcean1p0OpenCLBuild(kernel_outputdir).code_compiles(psy)
def test_use_stmts(kernel_outputdir): ''' Test that generating code for OpenCL results in the correct module use statements. ''' psy, _ = get_invoke("single_invoke.f90", API, idx=0) sched = psy.invokes.invoke_list[0].schedule otrans = OCLTrans() otrans.apply(sched) generated_code = str(psy.gen).lower() expected = '''\ subroutine invoke_0_compute_cu(cu_fld, p_fld, u_fld) use fortcl, only: create_rw_buffer use fortcl, only: get_num_cmd_queues, get_cmd_queues, get_kernel_by_name use clfortran use iso_c_binding''' assert expected in generated_code assert "if (first_time) then" in generated_code assert GOcean1p0OpenCLBuild(kernel_outputdir).code_compiles(psy)
def test_opencl_compiler_works(kernel_outputdir): ''' Check that the specified compiler works for a hello-world opencl example. This is done in this file to alert the user that all compiles tests are skipped if only the '--compile' command line option is used (instead of --compileopencl) ''' Compile.skip_if_opencl_compilation_disabled() example_ocl_code = ''' program hello USE fortcl write (*,*) "Hello" end program hello ''' old_pwd = kernel_outputdir.chdir() try: with open("hello_world_opencl.f90", "w") as ffile: ffile.write(example_ocl_code) GOcean1p0OpenCLBuild(kernel_outputdir).\ compile_file("hello_world_opencl.f90", link=True) finally: old_pwd.chdir()
def test_set_kern_args(kernel_outputdir): ''' Check that we generate the necessary code to set kernel arguments. ''' psy, _ = get_invoke("single_invoke_two_kernels.f90", API, idx=0) sched = psy.invokes.invoke_list[0].schedule otrans = OCLTrans() otrans.apply(sched) generated_code = str(psy.gen) # Check we've only generated one set-args routine assert generated_code.count("SUBROUTINE compute_cu_code_set_args(" "kernel_obj, nx, cu_fld, p_fld, u_fld)") == 1 # Declarations expected = '''\ SUBROUTINE compute_cu_code_set_args(kernel_obj, nx, cu_fld, p_fld, u_fld) USE clfortran, ONLY: clSetKernelArg USE iso_c_binding, ONLY: c_sizeof, c_loc, c_intptr_t USE ocl_utils_mod, ONLY: check_status INTEGER ierr INTEGER(KIND=c_intptr_t), target :: cu_fld, p_fld, u_fld INTEGER(KIND=c_intptr_t), target :: kernel_obj''' assert expected in generated_code expected = '''\ ! Set the arguments for the compute_cu_code OpenCL Kernel ierr = clSetKernelArg(kernel_obj, 0, C_SIZEOF(nx), C_LOC(nx)) ierr = clSetKernelArg(kernel_obj, 1, C_SIZEOF(cu_fld), C_LOC(cu_fld)) CALL check_status('clSetKernelArg: arg 1 of compute_cu_code', ierr) ierr = clSetKernelArg(kernel_obj, 2, C_SIZEOF(p_fld), C_LOC(p_fld)) CALL check_status('clSetKernelArg: arg 2 of compute_cu_code', ierr) ierr = clSetKernelArg(kernel_obj, 3, C_SIZEOF(u_fld), C_LOC(u_fld)) CALL check_status('clSetKernelArg: arg 3 of compute_cu_code', ierr) END SUBROUTINE compute_cu_code_set_args''' assert expected in generated_code assert generated_code.count("SUBROUTINE time_smooth_code_set_args(" "kernel_obj, nx, u_fld, " "unew_fld, uold_fld)") == 1 assert ("CALL compute_cu_code_set_args(kernel_compute_cu_code, " "p_fld%grid%nx, cu_fld%device_ptr, p_fld%device_ptr, " "u_fld%device_ptr)" in generated_code) assert GOcean1p0OpenCLBuild(kernel_outputdir).code_compiles(psy)