项目作者: LKedward

项目描述 :
A modern Fortran abstraction layer for OpenCL
高级语言: Fortran
项目地址: git://github.com/LKedward/focal.git
创建时间: 2019-10-28T11:13:11Z
项目社区:https://github.com/LKedward/focal

开源协议:MIT License

下载


Focal

License: MIT
fpm test
codecov

A modern Fortran abstraction layer for OpenCL

Focal is a module library which wraps calls to the OpenCL runtime API (using clfortran) 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:

Getting started

Quick example

The following fortran program calculates the sum of two large arrays using an OpenCL kernel.

  1. program sum
  2. !! Focal example program: calculate the sum of two arrays on an OpenCL device
  3. use Focal
  4. implicit none
  5. integer, parameter :: Nelem = 1E6 ! No. of array elements
  6. real, parameter :: sumVal = 10.0 ! Target value for array sum
  7. integer :: i ! Counter variable
  8. character(:), allocatable :: kernelSrc ! Kernel source string
  9. type(fclDevice) :: device ! Device object
  10. type(fclProgram) :: prog ! Focal program object
  11. type(fclKernel) :: sumKernel ! Focal kernel object
  12. real :: array1(Nelem) ! Host array 1
  13. real :: array2(Nelem) ! Host array 2
  14. type(fclDeviceFloat) :: array1_d ! Device array 1
  15. type(fclDeviceFloat) :: array2_d ! Device array 2
  16. ! Select device with most cores and create command queue
  17. device = fclInit(vendor='nvidia',sortBy='cores')
  18. call fclSetDefaultCommandQ(fclCreateCommandQ(device,enableProfiling=.true.))
  19. ! Load kernel from file and compile
  20. call fclSourceFromFile('examples/sum.cl',kernelSrc)
  21. prog = fclCompileProgram(kernelSrc)
  22. sumKernel = fclGetProgramKernel(prog,'sum')
  23. ! Initialise device arrays
  24. call fclInitBuffer(array1_d,Nelem)
  25. call fclInitBuffer(array2_d,Nelem)
  26. ! Initialise host array data
  27. do i=1,Nelem
  28. array1(i) = i
  29. end do
  30. array2 = sumVal - array1
  31. ! Copy data to device
  32. array1_d = array1
  33. array2_d = array2
  34. ! Set global work size equal to array length and launch kernel
  35. sumKernel%global_work_size(1) = Nelem
  36. call sumKernel%launch(Nelem,array1_d,array2_d)
  37. ! Copy result back to host and print out to check
  38. array2 = array2_d
  39. write(*,*) array2(1), array2(size(array2,1))
  40. end program sum

Where sum.cl contains the following openCL kernel:

  1. __kernel void sum(const int nElem, const __global float * v1, __global float * v2){
  2. int i = get_global_id(0);
  3. if(i < nElem) v2[i] += v1[i];
  4. }

Bundled third-party sources

The following open source libraries are used as dependencies and bundled in the repository (./external):

Acknowledgement

This work was funded by the MENtOR project, a UKVLN project
supported by the Engineering and Physical Sciences Research
Council (EPSRC) of the UK. Grant reference number
EP/S010378/1
.