RSECon23, Swansea
NVIDIA
2023-09-05
Except where otherwise noted, these presentation materials are licensed under the Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0) License.
To access links or follow on your own device these slides can be found at
https://jackatkinson.net/slides
The Institute of Computing for Climate Science
Climate models are large, complex, many-part systems.
We typically think of Deep Learning as an end-to-end process;
a black box with an input and an output.
Who’s that Pokémon?
\[\begin{bmatrix}\vdots\\a_{23}\\a_{24}\\a_{25}\\a_{26}\\a_{27}\\\vdots\\\end{bmatrix}=\begin{bmatrix}\vdots\\0\\0\\1\\0\\0\\\vdots\\\end{bmatrix}\] It’s Pikachu!
Neural Net by 3Blue1Brown under fair dealing.
Pikachu © The Pokemon Company, used under fair dealing.
Neural Net by 3Blue1Brown under fair dealing.
Pikachu © The Pokemon Company, used under fair dealing.
2 approaches:
Additional challenges:
Many large scientific models are written in Fortran (or C, or C++).
Much machine learning is conducted in Python.
Mathematical Bridge by cmglee used under CC BY-SA 3.0
PyTorch, the PyTorch logo and any related marks are trademarks of The Linux Foundation.”
TensorFlow, the TensorFlow logo and any related marks are trademarks of Google Inc.
There are 2 types of efficiency:
Computational
Developer
An ideal solution should:
inference-engine
, neural-fortran
, own solution etc.forpy.mod
file and compilePython
env
Python
runtime
xkcd #1987 by Randall Munroe, used under CC BY-NC 2.5
Both PyTorch and TensorFlow have C++ backends and provide APIs to access.
Binding Fortran to C is straightforward1 from 2003 using iso_c_binding
.
process_model
provided to extract required opaque parameters and use APINo-copy access in memory.
Indexing issues and associated reshape can be avoided with Torch accessor.
CMake
CMake is a trademark of Kitware.
pt2ts.py
script facilitates saving models to TorchScript.process_model
extracts TF model data.
The libraries are licensed under MIT and available as FOSS.
Replace the forpy connected net with our direct coupled approach.
Test both PyTorch and TensorFlow.
Given a Fortran program with model inputs in arrays,
the original coupling using forpy requires
lines of boilerplate code,
whilst our library takes
A fork of MiMA with these implementations of the interfaces is at:
https://github.com/DataWaveProject/MiMA-machine-learning
ie = forpy_initialize()
type(module_py) :: run_emulator
type(list) :: paths
type(object) :: model
type(tuple) :: args
type(str) :: py_model_dir
ie = str_create(py_model_dir, trim('/path/to/saved/model'))
ie = get_sys_path(paths)
ie = paths%append(py_model_dir)
! import python modules to `run_emulator`
ie = import_py(run_emulator, trim(model_name))
if (ie .ne. 0) then
call err_print
call error_mesg(__FILE__, __LINE__, "forpy model not loaded")
end if
! use python module `run_emulator` to load a trained model
ie = call_py(model, run_emulator, "name_of_init_function")
if (ie .ne. 0) then
call err_print
call error_mesg(__FILE__, __LINE__, "call to `initialize` failed")
end if
The libraries can be found at:
Torch: https://github.com/Cambridge-ICCS/fortran-pytorch-lib
TensorFlow: https://github.com/Cambridge-ICCS/fortran-tf-lib
Slides available at: https://jackatkinson.net/slides/RSECon23/RSECon23.html
Get in touch:
The ICCS is funded by
The libraries can be found at:
Their implementation in the MiMA model can be found at:
https://github.com/DataWaveProject/MiMA-machine-learning
Benchmarking of PyTorch can be found at:
https://github.com/Cambridge-ICCS/fortran-pytorch-lib-benchmark/
Neccessary imports:
use, intrinsic :: iso_c_binding, only: c_int64_t, c_float, c_char, &
c_null_char, c_ptr, c_loc
use ftorch
Loading a pytorch model:
Tensor creation from Fortran arrays:
! Fortran variables
real, dimension(:,:), target :: SST, model_output
! C/Torch variables
integer(c_int), parameter :: dims_T = 2
integer(c_int64_t) :: shape_T(dims_T)
integer(c_int), parameter :: n_inputs = 1
type(torch_tensor), dimension(n_inputs), target :: model_inputs
type(torch_tensor) :: model_output_T
shape_T = shape(SST)
model_inputs(1) = torch_tensor_from_blob(c_loc(SST), dims_T, shape_T &
torch_kFloat64, torch_kCPU)
model_output = torch_tensor_from_blob(c_loc(output), dims_T, shape_T, &
torch_kFloat64, torch_kCPU)
Running the model
Cleaning up:
Timings (real seconds) for computing gravity wave drag in-situ.1
Forpy | Direct | % Direct/Forpy | |
---|---|---|---|
PyTorch | 94.43 s | 134.81 s | 142.8 % |
TensorFlow | 667.16 s | 170.31 s | 25.5 % |
Timing data (real seconds) for benchmarking gravity wave drag with PyTorch on CSD3.
intel | Forpy | Direct | % Direct/Forpy |
---|---|---|---|
Mean | 0.3126 s | 0.3509 s | 112.3 % |
Std | 0.0420 s | 0.0547 s | - |
gcc | Forpy | Direct | % Direct/Forpy |
---|---|---|---|
Mean | 0.3405 s | 0.3669 s | 107.7 % |
Std | 0.0449 s | 0.0586 s | - |