Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

142 test assert rebase #174

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e66416f
Extend FTorch to cover 5-dimensional tensors.
jatkinson1000 Sep 30, 2024
e2b581d
Update torch_tensor_to_array to check for association rather than sha…
jatkinson1000 Oct 1, 2024
f8e9339
Introduce utils module
jwallwork23 Sep 13, 2024
0d443ea
Use assertions in example 2
jwallwork23 Sep 13, 2024
b63cd88
Multiply rtol by expected value in assertion - thanks @dorchard
jwallwork23 Sep 13, 2024
6a60bfc
Rework assert function; implement 1d array version
jwallwork23 Sep 13, 2024
6edc755
Use assertions in example 1
jwallwork23 Sep 13, 2024
969adc0
Use assertions in example 4
jwallwork23 Sep 13, 2024
a888b31
Non-zero error codes
jwallwork23 Sep 13, 2024
a71e8a3
Use assertions in example 5
jwallwork23 Sep 13, 2024
7067b3e
Always check pointer array shape
jwallwork23 Sep 13, 2024
e138de1
Lint
jwallwork23 Sep 13, 2024
50753d9
Run integration tests in verbose mode in CI
jwallwork23 Sep 13, 2024
c58f76a
Put shape error check back in right place
jwallwork23 Sep 13, 2024
e592e89
Better to write shape explicitly
jwallwork23 Sep 13, 2024
4b22ca3
More accurate comment on shape error
jwallwork23 Sep 13, 2024
5a322e0
Rename utils->ftorch_test_utils
jwallwork23 Sep 16, 2024
30d71bc
Make autograd example 7
jwallwork23 Sep 16, 2024
879fdf1
Update ftorch.f90 using fypp after rebase.
jatkinson1000 Oct 1, 2024
75bd549
Update workflow to dump log.
jatkinson1000 Oct 1, 2024
3085d21
Update fypp to write out more information for debugging workflow.
jatkinson1000 Oct 1, 2024
948ed16
Add more debugging output and set autograd pointer to null.
jatkinson1000 Oct 5, 2024
d1bbf2a
Set autograd pointer to not null.
jatkinson1000 Oct 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/test_suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,9 @@ jobs:
- name: Integration tests
run: |
. ftorch/bin/activate
./run_integration_tests.sh
./run_integration_tests.sh -V

- name: write log
if: always()
run: |
cat /home/runner/work/FTorch/FTorch/src/build/test/examples/7_Autograd/Testing/Temporary/LastTest.log
6 changes: 0 additions & 6 deletions examples/1_SimpleNet/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ if(CMAKE_BUILD_TESTS)
# 1. Check the PyTorch model runs and its outputs meet expectations
add_test(NAME simplenet
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/simplenet.py)
set_tests_properties(simplenet PROPERTIES PASS_REGULAR_EXPRESSION
"0., 2., 4., 6., 8.")

# 2. Check the model is saved to file in the expected location with the pt2ts.py script
add_test(NAME pt2ts
Expand All @@ -40,15 +38,11 @@ if(CMAKE_BUILD_TESTS)
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/simplenet_infer_python.py
${PROJECT_BINARY_DIR} # Command line argument: filepath to find the model
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(simplenet_infer_python PROPERTIES PASS_REGULAR_EXPRESSION
"0., 2., 4., 6., 8.")

# 4. Check the model can be loaded from file and run in Fortran and that its outputs
# meet expectations
add_test(NAME simplenet_infer_fortran
COMMAND simplenet_infer_fortran
${PROJECT_BINARY_DIR}/saved_simplenet_model_cpu.pt # Command line argument: model file
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(simplenet_infer_fortran PROPERTIES PASS_REGULAR_EXPRESSION
" 0.00000000 2.00000000 4.00000000 6.00000000 8.00000000")
endif()
6 changes: 5 additions & 1 deletion examples/1_SimpleNet/simplenet.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,9 @@ def forward(self, batch: torch.Tensor) -> torch.Tensor:
model = SimpleNet()
model.eval()

input_tensor = torch.Tensor([0.0, 1.0, 2.0, 3.0, 4.0])
with torch.no_grad():
print(model(torch.Tensor([0.0, 1.0, 2.0, 3.0, 4.0])))
output_tensor = model(input_tensor)

print(output_tensor)
assert torch.allclose(output_tensor, 2 * input_tensor)
15 changes: 15 additions & 0 deletions examples/1_SimpleNet/simplenet_infer_fortran.f90
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ program inference
! Import our library for interfacing with PyTorch
use ftorch

! Import our tools module for testing utils
use ftorch_test_utils, only : assert_real_array_1d

implicit none

! Set working precision for reals
Expand All @@ -17,6 +20,7 @@ program inference
! Set up Fortran data structures
real(wp), dimension(5), target :: in_data
real(wp), dimension(5), target :: out_data
real(wp), dimension(5), target :: expected
integer :: tensor_layout(1) = [1]

! Set up Torch data structures
Expand All @@ -25,6 +29,9 @@ program inference
type(torch_tensor), dimension(1) :: in_tensors
type(torch_tensor), dimension(1) :: out_tensors

! Flag for testing
logical :: test_pass

! Get TorchScript model file as a command line argument
num_args = command_argument_count()
allocate(args(num_args))
Expand All @@ -46,9 +53,17 @@ program inference
call torch_model_forward(model, in_tensors, out_tensors)
write (*,*) out_data(:)

! Check output tensor matches expected value
expected = [0.0, 2.0, 4.0, 6.0, 8.0]
test_pass = assert_real_array_1d(out_data, expected, test_name="SimpleNet", rtol=1e-5)

! Cleanup
call torch_delete(model)
call torch_delete(in_tensors)
call torch_delete(out_tensors)

if (.not. test_pass) then
stop 999
end if

end program inference
2 changes: 2 additions & 0 deletions examples/1_SimpleNet/simplenet_infer_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,5 @@ def deploy(saved_model: str, device: str, batch_size: int = 1) -> torch.Tensor:
result = deploy(saved_model_file, device_to_run, batch_size_to_run)

print(result)

assert torch.allclose(result, torch.Tensor([0.0, 2.0, 4.0, 6.0, 8.0]))
8 changes: 1 addition & 7 deletions examples/2_ResNet18/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ if(CMAKE_BUILD_TESTS)
add_test(NAME resnet18
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/resnet18.py
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
set_tests_properties(resnet18 PROPERTIES PASS_REGULAR_EXPRESSION "0.88462")
set_tests_properties(resnet18 PROPERTIES PASS_REGULAR_EXPRESSION "0.04580")
set_tests_properties(resnet18 PROPERTIES PASS_REGULAR_EXPRESSION "0.04427")
set_tests_properties(resnet18 PROPERTIES PASS_REGULAR_EXPRESSION "0.00562")
set_tests_properties(resnet18 PROPERTIES PASS_REGULAR_EXPRESSION "0.00465")

# 2. Check the model is saved to file in the expected location with the pt2ts.py script
add_test(NAME pt2ts
Expand All @@ -43,7 +38,6 @@ if(CMAKE_BUILD_TESTS)
add_test(NAME resnet_infer_fortran
COMMAND resnet_infer_fortran
${PROJECT_BINARY_DIR}/saved_resnet18_model_cpu.pt # Command line argument: model file
${PROJECT_SOURCE_DIR}/data # COmmand line argument: data directory filepath
${PROJECT_SOURCE_DIR}/data # Command line argument: data directory filepath
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(resnet_infer_fortran PROPERTIES PASS_REGULAR_EXPRESSION "0.88462")
endif()
11 changes: 10 additions & 1 deletion examples/2_ResNet18/resnet18.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def run_model(model: torch.nn.Module, precision: type) -> None:
tensor_shape = np.array(input_batch.numpy()).transpose().shape
np_data = np_data.reshape(tensor_shape)
np_data = np_data.transpose()
assert np.array_equal(np_data, input_batch.numpy()) is True
assert np.array_equal(np_data, input_batch.numpy())
print("done.")

print("Running ResNet-18 model for input...", end="")
Expand Down Expand Up @@ -119,6 +119,15 @@ def print_top_results(output: torch.Tensor) -> None:
f"{categories[cat_id]} (id={cat_id}): probability = {top5_prob[i].item()}"
)

expected_prob = [
0.8846225142478943,
0.0458051748573780,
0.0442761555314064,
0.0056213834322989,
0.0046520135365427,
]
assert np.allclose(top5_prob, expected_prob, rtol=1e-5)


if __name__ == "__main__":
np_precision = np.float32
Expand Down
45 changes: 13 additions & 32 deletions examples/2_ResNet18/resnet_infer_fortran.f90
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
program inference

use, intrinsic :: iso_fortran_env, only : sp => real32

! Import our library for interfacing with PyTorch
use :: ftorch
use ftorch

! Import our tools module for testing utils
use ftorch_test_utils, only : assert_real

implicit none

Expand Down Expand Up @@ -52,6 +56,9 @@ subroutine main()
character(len=100) :: categories(N_cats)
real(wp) :: probability

! Flag for testing
logical :: test_pass

! Get TorchScript model file as a command line argument
num_args = command_argument_count()
allocate(args(num_args))
Expand Down Expand Up @@ -95,7 +102,7 @@ subroutine main()
probability = maxval(probabilities)

! Check top probability matches expected value
call assert_real(probability, expected_prob, test_name="Check probability", rtol=1e-5)
test_pass = assert_real(probability, expected_prob, test_name="Check probability", rtol=1e-5)

write (*,*) "Top result"
write (*,*) ""
Expand All @@ -110,6 +117,10 @@ subroutine main()
deallocate(probabilities)
deallocate(args)

if (.not. test_pass) then
stop 999
end if

end subroutine main

subroutine load_data(filename, tensor_length, in_data)
Expand Down Expand Up @@ -182,34 +193,4 @@ subroutine calc_probs(out_data, probabilities)

end subroutine calc_probs

subroutine assert_real(a, b, test_name, rtol)

implicit none

character(len=*) :: test_name
real, intent(in) :: a, b
real, optional :: rtol
real :: relative_error, rtol_value

character(len=15) :: pass, fail

fail = char(27)//'[31m'//'FAILED'//char(27)//'[0m'
pass = char(27)//'[32m'//'PASSED'//char(27)//'[0m'

if (.not. present(rtol)) then
rtol_value = 1e-5
else
rtol_value = rtol
end if

relative_error = abs(a/b - 1.)

if (relative_error > rtol_value) then
write(*, '(A, " :: [", A, "] maximum relative error = ", E11.4)') fail, trim(test_name), relative_error
else
write(*, '(A, " :: [", A, "] maximum relative error = ", E11.4)') pass, trim(test_name), relative_error
end if

end subroutine assert_real

end program inference
12 changes: 0 additions & 12 deletions examples/4_MultiIO/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ if(CMAKE_BUILD_TESTS)
# 1. Check the PyTorch model runs and its outputs meet expectations
add_test(NAME multiionet
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/multiionet.py)
set_tests_properties(multiionet PROPERTIES PASS_REGULAR_EXPRESSION
"0., 2., 4., 6.")
set_tests_properties(multiionet PROPERTIES PASS_REGULAR_EXPRESSION
"0., -3., -6., -9.")

# 2. Check the model is saved to file in the expected location with the pt2ts.py script
add_test(NAME pt2ts
Expand All @@ -42,19 +38,11 @@ if(CMAKE_BUILD_TESTS)
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/multiionet_infer_python.py
${PROJECT_BINARY_DIR} # Command line argument: filepath to find the model
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(multiionet_infer_python PROPERTIES PASS_REGULAR_EXPRESSION
"0., 2., 4., 6.")
set_tests_properties(multiionet_infer_python PROPERTIES PASS_REGULAR_EXPRESSION
"0., -3., -6., -9.")

# 4. Check the model can be loaded from file and run in Fortran and that its outputs
# meet expectations
add_test(NAME multiionet_infer_fortran
COMMAND multiionet_infer_fortran
${PROJECT_BINARY_DIR}/saved_multiio_model_cpu.pt # Command line argument: model file
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(multiionet_infer_fortran PROPERTIES PASS_REGULAR_EXPRESSION
" 0.00000000 2.00000000 4.00000000 6.00000000")
set_tests_properties(multiionet_infer_fortran PROPERTIES PASS_REGULAR_EXPRESSION
" 0.00000000 -3.00000000 -6.00000000 -9.00000000")
endif()
17 changes: 11 additions & 6 deletions examples/4_MultiIO/multiionet.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,15 @@ def forward(self, batch1: torch.Tensor, batch2: torch.Tensor):
model = MultiIONet()
model.eval()

input_tensors = (
torch.Tensor([0.0, 1.0, 2.0, 3.0]),
torch.Tensor([-0.0, -1.0, -2.0, -3.0]),
)

with torch.no_grad():
print(
model(
torch.Tensor([0.0, 1.0, 2.0, 3.0]),
torch.Tensor([-0.0, -1.0, -2.0, -3.0]),
)
)
output_tensors = model(*input_tensors)

print(output_tensors)

for output, input, scale_factor in zip(output_tensors, input_tensors, (2, 3)):
assert torch.allclose(output, scale_factor * input)
17 changes: 17 additions & 0 deletions examples/4_MultiIO/multiionet_infer_fortran.f90
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ program inference
! Import our library for interfacing with PyTorch
use ftorch

! Import our tools module for testing utils
use ftorch_test_utils, only : assert_real_array_1d

implicit none

! Set working precision for reals
Expand All @@ -19,6 +22,7 @@ program inference
real(wp), dimension(4), target :: in_data2
real(wp), dimension(4), target :: out_data1
real(wp), dimension(4), target :: out_data2
real(wp), dimension(4) :: expected
integer :: tensor_layout(1) = [1]

! Set up Torch data structures
Expand All @@ -27,6 +31,9 @@ program inference
type(torch_tensor), dimension(2) :: in_tensors
type(torch_tensor), dimension(2) :: out_tensors

! Flag for testing
logical :: test_pass

! Get TorchScript model file as a command line argument
num_args = command_argument_count()
allocate(args(num_args))
Expand All @@ -52,9 +59,19 @@ program inference
write (*,*) out_data1
write (*,*) out_data2

! Check output tensors match expected values
expected = [0.0, 2.0, 4.0, 6.0]
test_pass = assert_real_array_1d(out_data1, expected, test_name="MultiIO array1", rtol=1e-5)
expected = [0.0, -3.0, -6.0, -9.0]
test_pass = assert_real_array_1d(out_data2, expected, test_name="MultiIO array2", rtol=1e-5)

! Cleanup
call torch_delete(model)
call torch_delete(in_tensors)
call torch_delete(out_tensors)

if (.not. test_pass) then
stop 999
end if

end program inference
8 changes: 8 additions & 0 deletions examples/4_MultiIO/multiionet_infer_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,11 @@ def deploy(saved_model: str, device: str, batch_size: int = 1) -> torch.Tensor:
result = deploy(saved_model_file, device_to_run, batch_size_to_run)

print(result)

expected_tensors = (
torch.Tensor([0.0, 2.0, 4.0, 6.0]),
torch.Tensor([-0.0, -3.0, -6.0, -9.0]),
)

for got, expected in zip(result, expected_tensors):
assert torch.allclose(got, expected)
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,9 @@ if(CMAKE_BUILD_TESTS)
# 1. Check the Python Autograd script runs successfully
add_test(NAME pyautograd
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/autograd.py)
set_tests_properties(pyautograd PROPERTIES PASS_REGULAR_EXPRESSION
"-12., 65.")

# 2. Check the Fortran Autograd script runs successfully
add_test(NAME fautograd
COMMAND autograd
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(fautograd PROPERTIES PASS_REGULAR_EXPRESSION
"2.00000000 3.00000000")
endif()
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ program example
! Import our library for interfacing with PyTorch's Autograd module
use ftorch

! Import our tools module for testing utils
use ftorch_test_utils, only : assert_real_array_1d

implicit none

! Set working precision for reals
Expand All @@ -14,8 +17,12 @@ program example
! Set up Fortran data structures
real(wp), dimension(2), target :: in_data
real(wp), dimension(:), pointer :: out_data
real(wp), dimension(2) :: expected
integer :: tensor_layout(1) = [1]

! Flag for testing
logical :: test_pass

! Set up Torch data structures
type(torch_tensor) :: a

Expand All @@ -24,11 +31,19 @@ program example
call torch_tensor_from_array(a, in_data, tensor_layout, torch_kCPU)

! Extract a Fortran array from a Torch tensor
call torch_tensor_to_array(a, out_data, shape(in_data))
call torch_tensor_to_array(a, out_data, [2])
write (*,*) "a = ", out_data(:)

! Check output tensor matches expected value
expected = [2.0, 3.0]
test_pass = assert_real_array_1d(out_data, expected, test_name="torch_tensor_to_array", rtol=1e-5)

! Cleanup
nullify(out_data)
call torch_tensor_delete(a)

if (.not. test_pass) then
stop 999
end if

end program example
Loading
Loading