- Notifications
You must be signed in to change notification settings - Fork8
A modern Fortran abstraction layer for OpenCL
License
LKedward/focal
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Focal is a module library which wraps calls to the OpenCL runtime API (usingclfortran) with a higher abstraction level appropriate to the Fortran language.
The goal of Focal is to provide a concise and accessible Fortran interface to the OpenCL API while retaining the full functionality thereof.This is desirable in Fortran which as a language provides a higher level of abstraction than C; importantly this allows scientists and engineers to focus on their domain specific problem rather than details of low-level implementation.
Key features:
- Removes use of c pointers to call OpenCL API
- Provides a level of type safety using typed buffer objects
- Decreases verbosity of OpenCL API calls while still providing the same functionality
- Abstracts away low level details, such as size in bytes
- Contains built-in customisable error handling for all OpenCL API calls
- Contains built-in 'debug' mode for checking program correctness
- Contains build-in routines for collecting and presented profiling information
Project status: v1.0.1 stable release
Documentation:lkedward.github.io/focal-docs
License:MIT
Prerequisites:
- GNU make utility
- Fortran compiler supporting the 2008 standard (tested in the CI with
gfortran
9.3.0 andifort
(oneAPI) 21.3.0 ) - An OpenCL development library (One of:Intel OpenCL SDK,NVIDIA CUDA Toolkit,AMD Radeon Software )
- Building the Focal Library
- Using and linking Focal
- Quickstart programming guide
- Example programs
- Lattice Boltzmann demo
The following fortran program calculates the sum of two large arrays using an OpenCL kernel.
program sum!! Focal exampleprogram: calculate the sum of two arrays on an OpenCL deviceuse Focalimplicit noneinteger,parameter:: Nelem=1E6 ! No. of array elementsreal,parameter:: sumVal=10.0 ! Target value for array suminteger:: i ! Counter variablecharacter(:), allocatable:: kernelSrc ! Kernel source stringtype(fclDevice):: device ! Device objecttype(fclProgram):: prog ! Focalprogram objecttype(fclKernel):: sumKernel ! Focal kernel objectreal:: array1(Nelem) ! Host array1real:: array2(Nelem) ! Host array2type(fclDeviceFloat):: array1_d ! Device array1type(fclDeviceFloat):: array2_d ! Device array2! Select device with most cores and create command queuedevice= fclInit(vendor='nvidia',sortBy='cores')call fclSetDefaultCommandQ(fclCreateCommandQ(device,enableProfiling=.true.))! Load kernel from file and compilecall fclSourceFromFile('examples/sum.cl',kernelSrc)prog= fclCompileProgram(kernelSrc)sumKernel= fclGetProgramKernel(prog,'sum')! Initialise device arrayscall fclInitBuffer(array1_d,Nelem)call fclInitBuffer(array2_d,Nelem)! Initialise host arraydatado i=1,Nelem array1(i)= iend doarray2= sumVal- array1! Copydatato devicearray1_d= array1array2_d= array2! Set global work size equalto array length and launch kernelsumKernel%global_work_size(1)= Nelemcall sumKernel%launch(Nelem,array1_d,array2_d)! Copy result backto host andprintoutto checkarray2= array2_dwrite(*,*) array2(1), array2(size(array2,1))end program sum
Wheresum.cl
contains the following openCL kernel:
__kernelvoidsum(constintnElem,const__globalfloat*v1,__globalfloat*v2){inti=get_global_id(0);if(i<nElem)v2[i]+=v1[i];}
The following open source libraries are used as dependencies and bundled in the repository (./external):
fortran-utils/sorting (MIT license)
clfortran (LGPL)
M_strings (Unlicense/Public domain)
This work was funded by the MENtOR project, a UKVLN projectsupported by the Engineering and Physical Sciences ResearchCouncil (EPSRC) of the UK. Grant reference numberEP/S010378/1.
About
A modern Fortran abstraction layer for OpenCL