From 8bdd6ff3cb9cd05e1fab57e5eb3b3cacd144ee14 Mon Sep 17 00:00:00 2001 From: Nick Wogan Date: Thu, 28 Mar 2024 14:32:24 -0700 Subject: [PATCH] rename and test --- .github/workflows/test.yaml | 44 ++++++++++ .gitignore | 3 +- CMakeLists.txt | 2 +- src/CMakeLists.txt | 17 ++-- src/forwarddif.f90 | 7 -- src/forwarddiff.f90 | 7 ++ ...arddif_const.f90 => forwarddiff_const.f90} | 2 +- ...ivative.f90 => forwarddiff_derivative.f90} | 6 +- ...rwarddif_dual.f90 => forwarddiff_dual.f90} | 4 +- test/CMakeLists.txt | 6 +- ...st_forwarddif.f90 => test_forwarddiff.f90} | 25 ++++-- test/test_jax.py | 87 +++++++++++++++++++ 12 files changed, 172 insertions(+), 38 deletions(-) create mode 100644 .github/workflows/test.yaml delete mode 100644 src/forwarddif.f90 create mode 100644 src/forwarddiff.f90 rename src/{forwarddif_const.f90 => forwarddiff_const.f90} (67%) rename src/{forwarddif_derivative.f90 => forwarddiff_derivative.f90} (92%) rename src/{forwarddif_dual.f90 => forwarddiff_dual.f90} (99%) rename test/{test_forwarddif.f90 => test_forwarddiff.f90} (80%) create mode 100644 test/test_jax.py diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..ea16cbd --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,44 @@ +name: test + +on: push + +env: + BUILD_TYPE: Debug + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Setup Fortran + uses: awvwgk/setup-fortran@main + id: setup-fortran + with: + compiler: gcc + version: 11 + + - name: Setup Python + uses: actions/setup-python@v3 + with: + python-version: 3.10 + + - name: Install dependencies + run: | + sudo apt-get install valgrind + python -m pip install --upgrade pip + python -m pip install jax + + - name: configure cmake + run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + + - name: build + run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + + - name: test + working-directory: ${{github.workspace}}/build + run: | + ./tests/test_forwarddiff + valgrind --error-exitcode=1 --leak-check=full ./tests/test_forwarddiff + python ../tests/test_jax.py diff --git a/.gitignore b/.gitignore index c795b05..751831e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -build \ No newline at end of file +build +.DS_Store \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index a2809cf..d506bb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION "3.14") -project(FORWARDDIF LANGUAGES Fortran) +project(FORWARDDIFF LANGUAGES Fortran) set(CMAKE_Fortran_MODULE_DIRECTORY "${CMAKE_BINARY_DIR}/modules") add_subdirectory(src) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 745688d..c077252 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,13 +1,6 @@ -add_library(forwarddif - forwarddif_const.f90 - forwarddif_dual.f90 - forwarddif_derivative.f90 - forwarddif.f90 +add_library(forwarddiff + forwarddiff_const.f90 + forwarddiff_dual.f90 + forwarddiff_derivative.f90 + forwarddiff.f90 ) - -# add_executable(test_forwarddif test_forwarddif.f90) -# target_link_libraries(test_forwarddif forwarddif) - -# add_library(dnad dnad.F90) -# add_executable(test_forwarddif test_forwarddif.f90) -# target_link_libraries(test_forwarddif dnad) \ No newline at end of file diff --git a/src/forwarddif.f90 b/src/forwarddif.f90 deleted file mode 100644 index 0214c5e..0000000 --- a/src/forwarddif.f90 +++ /dev/null @@ -1,7 +0,0 @@ -module forwarddif - use forwarddif_const - use forwarddif_dual - use forwarddif_derivative - implicit none - public -end module \ No newline at end of file diff --git a/src/forwarddiff.f90 b/src/forwarddiff.f90 new file mode 100644 index 0000000..c72857f --- /dev/null +++ b/src/forwarddiff.f90 @@ -0,0 +1,7 @@ +module forwarddiff + use forwarddiff_const + use forwarddiff_dual + use forwarddiff_derivative + implicit none + public +end module \ No newline at end of file diff --git a/src/forwarddif_const.f90 b/src/forwarddiff_const.f90 similarity index 67% rename from src/forwarddif_const.f90 rename to src/forwarddiff_const.f90 index 4d3ccb0..ad8104e 100644 --- a/src/forwarddif_const.f90 +++ b/src/forwarddiff_const.f90 @@ -1,3 +1,3 @@ -module forwarddif_const +module forwarddiff_const use iso_fortran_env, only: wp => real32 end module \ No newline at end of file diff --git a/src/forwarddif_derivative.f90 b/src/forwarddiff_derivative.f90 similarity index 92% rename from src/forwarddif_derivative.f90 rename to src/forwarddiff_derivative.f90 index d534dfa..ea0abc1 100644 --- a/src/forwarddif_derivative.f90 +++ b/src/forwarddiff_derivative.f90 @@ -1,6 +1,6 @@ -module forwarddif_derivative - use forwarddif_const, only: wp - use forwarddif_dual, only: dual +module forwarddiff_derivative + use forwarddiff_const, only: wp + use forwarddiff_dual, only: dual implicit none private diff --git a/src/forwarddif_dual.f90 b/src/forwarddiff_dual.f90 similarity index 99% rename from src/forwarddif_dual.f90 rename to src/forwarddiff_dual.f90 index 44429a4..8394891 100644 --- a/src/forwarddif_dual.f90 +++ b/src/forwarddiff_dual.f90 @@ -1,6 +1,6 @@ -module forwarddif_dual +module forwarddiff_dual use ieee_arithmetic, only: ieee_value, ieee_quiet_nan - use forwarddif_const, only: wp + use forwarddiff_const, only: wp implicit none private diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 16c46b3..af4930c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,3 +1,3 @@ -add_executable(test_forwarddif test_forwarddif.f90) -target_link_libraries(test_forwarddif forwarddif) -target_include_directories(test_forwarddif PUBLIC ${CMAKE_Fortran_MODULE_DIRECTORY}) \ No newline at end of file +add_executable(test_forwarddiff test_forwarddiff.f90) +target_link_libraries(test_forwarddiff forwarddiff) +target_include_directories(test_forwarddiff PUBLIC ${CMAKE_Fortran_MODULE_DIRECTORY}) \ No newline at end of file diff --git a/test/test_forwarddif.f90 b/test/test_forwarddiff.f90 similarity index 80% rename from test/test_forwarddif.f90 rename to test/test_forwarddiff.f90 index e27af4a..7de109e 100644 --- a/test/test_forwarddif.f90 +++ b/test/test_forwarddiff.f90 @@ -1,5 +1,5 @@ -program test_forwarddif - use forwarddif, only: wp, derivative, grad +program test_forwarddiff + use forwarddiff, only: wp, derivative, grad implicit none call test() @@ -9,30 +9,39 @@ subroutine test() real(wp) :: x, f, dfdx real(wp) :: xx(2), dfdx1(2) + open(unit=2,file='test.dat',status='replace',form='unformatted') + x = 10.0_wp call derivative(func_operators, x, f, dfdx) print*,f, dfdx + write(2) f, dfdx x = 10.0_wp call derivative(func_intrinsics1, x, f, dfdx) print*,f, dfdx + write(2) f, dfdx x = 0.1_wp call derivative(func_intrinsics2, x, f, dfdx) print*,f, dfdx + write(2) f, dfdx xx = [1.0_wp, 2.0_wp] call grad(func_grad1, xx, f, dfdx1) print*,f, dfdx1 + write(2) f, dfdx1 - xx = [1.0_wp, 2.0_wp] + xx = [3.0_wp, 4.0_wp] call grad(func_grad2, xx, f, dfdx1) print*,f, dfdx1 + write(2) f, dfdx1 + + close(2) end subroutine function func_operators(x) result(res) - use forwarddif_dual + use forwarddiff_dual type(dual), intent(in) :: x type(dual) :: res @@ -45,7 +54,7 @@ function func_operators(x) result(res) end function function func_intrinsics1(x) result(res) - use forwarddif_dual + use forwarddiff_dual type(dual), intent(in) :: x type(dual) :: res @@ -61,7 +70,7 @@ function func_intrinsics1(x) result(res) end function function func_intrinsics2(x) result(res) - use forwarddif_dual + use forwarddiff_dual type(dual), intent(in) :: x type(dual) :: res @@ -78,14 +87,14 @@ function func_intrinsics2(x) result(res) end function function func_grad1(x) result(res) - use forwarddif_dual + use forwarddiff_dual type(dual), intent(in) :: x(:) type(dual) :: res res = x(1)*x(1)*x(2) + x(1) + x(2) end function function func_grad2(x) result(res) - use forwarddif_dual + use forwarddiff_dual type(dual), intent(in) :: x(:) type(dual) :: res res = sum(x*3.14_wp) diff --git a/test/test_jax.py b/test/test_jax.py new file mode 100644 index 0000000..106cba5 --- /dev/null +++ b/test/test_jax.py @@ -0,0 +1,87 @@ +import jax +from jax import numpy as np +from scipy.io import FortranFile + +def func_operators(x): + res = x + x + 3.0 + x + res = res - x - 3.0 - x + res = res*x + 2.0*x + x*-5.0 + res = res/x + 2.0/x + x/5.0 + res = res**x + res**1.5 + return res + +def func_intrinsics1(x): + res = np.abs(x) + res = res + np.cos(x) + res = res + np.exp(x) + res = res + np.log(x) + res = res + np.log10(x) + res = res + np.sin(x) + res = res + np.tan(x) + res = res + np.sqrt(x) + return res + +def func_intrinsics2(x): + res = np.arccos(x) + res = res + np.arcsin(x) + res = res + np.arctan(x) + res = np.maximum(res, x) + res = np.maximum(res, 1.0) + res = np.maximum(1.0, res) + res = np.minimum(res, res) + res = np.minimum(res, 2.0) + res = np.minimum(2.0, res) + return res + +def func_grad1(x): + res = x[0]*x[0]*x[1] + x[0] + x[1] + return res + +def func_grad2(x): + res = np.sum(x*3.14) + return res + +def test(): + fil = FortranFile('test.dat','r') + + x = np.array(10.0,dtype=np.float32) + f = func_operators(x) + dfdx = jax.grad(func_operators)(x) + f1, dfdx1 = fil.read_record(np.float32) + print(f/f1,dfdx/dfdx1) + assert np.isclose(f,f1) and np.isclose(dfdx,dfdx1) + + x = np.array(10.0,dtype=np.float32) + f = func_intrinsics1(x) + dfdx = jax.grad(func_intrinsics1)(x) + f1, dfdx1 = fil.read_record(np.float32) + print(f/f1,dfdx/dfdx1) + assert np.isclose(f,f1) and np.isclose(dfdx,dfdx1) + + x = np.array(0.1,dtype=np.float32) + f = func_intrinsics2(x) + dfdx = jax.grad(func_intrinsics2)(x) + f1, dfdx1 = fil.read_record(np.float32) + print(f/f1,dfdx/dfdx1) + assert np.isclose(f,f1) and np.isclose(dfdx,dfdx1) + + x = np.array([1, 2],dtype=np.float32) + f = func_grad1(x) + dfdx = jax.grad(func_grad1)(x) + tmp = fil.read_record(np.float32) + f1, dfdx1 = tmp[0],tmp[1:] + print(f/f1,dfdx/dfdx1) + assert np.isclose(f,f1) and np.all(np.isclose(dfdx,dfdx1)) + + x = np.array([3, 4],dtype=np.float32) + f = func_grad2(x) + dfdx = jax.grad(func_grad2)(x) + tmp = fil.read_record(np.float32) + f1, dfdx1 = tmp[0],tmp[1:] + print(f/f1,dfdx/dfdx1) + assert np.isclose(f,f1) and np.all(np.isclose(dfdx,dfdx1)) + + fil.close() + +if __name__ == "__main__": + test()