Skip to content

Commit

Permalink
Merge pull request #143 from Cambridge-ICCS/pre-AG-API-changes
Browse files Browse the repository at this point in the history
Adjust the API in anticipation of future operator overloading for AutoGrad functionality
  • Loading branch information
jatkinson1000 authored Jun 27, 2024
2 parents ac4c14f + bfbbce9 commit e92ad9e
Show file tree
Hide file tree
Showing 10 changed files with 325 additions and 295 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ examples for performing coupling.
```fortran
use ftorch
...
type(torch_module) :: model
type(torch_tensor), dimension(n_inputs) :: model_inputs_arr
type(torch_tensor) :: model_output
type(torch_model) :: model
type(torch_tensor), dimension(n_inputs) :: model_inputs_arr
type(torch_tensor), dimension(n_outputs) :: model_output_arr
...
model = torch_module_load("/my/saved/TorchScript/model.pt")
model_inputs_arr(1) = torch_tensor_from_array(input_fortran, in_layout, torch_kCPU)
model_output = torch_tensor_from_array(output_fortran, out_layout, torch_kCPU)
call torch_model_load(model, "/my/saved/TorchScript/model.pt")
call torch_tensor_from_array(model_inputs_arr(1), input_fortran, in_layout, torch_kCPU)
call torch_tensor_from_array(model_output_arr(1), output_fortran, out_layout, torch_kCPU)
call torch_module_forward(model, model_input_arr, n_inputs, model_output)
call torch_model_forward(model, model_input_arr, model_output_arr)
```

The following presentations provide an introduction and overview of _FTorch_:
Expand Down
12 changes: 6 additions & 6 deletions examples/1_SimpleNet/simplenet_infer_fortran.f90
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ program inference

! Set up Torch data structures
! The net, a vector of input tensors (in this case we only have one), and the output tensor
type(torch_module) :: model
type(torch_model) :: model
type(torch_tensor), dimension(1) :: in_tensors
type(torch_tensor), dimension(1) :: out_tensors

Expand All @@ -36,18 +36,18 @@ program inference
in_data = [0.0, 1.0, 2.0, 3.0, 4.0]

! Create Torch input/output tensors from the above arrays
in_tensors(1) = torch_tensor_from_array(in_data, tensor_layout, torch_kCPU)
out_tensors(1) = torch_tensor_from_array(out_data, tensor_layout, torch_kCPU)
call torch_tensor_from_array(in_tensors(1), in_data, tensor_layout, torch_kCPU)
call torch_tensor_from_array(out_tensors(1), out_data, tensor_layout, torch_kCPU)

! Load ML model
model = torch_module_load(args(1))
call torch_model_load(model, args(1))

! Infer
call torch_module_forward(model, in_tensors, out_tensors)
call torch_model_forward(model, in_tensors, out_tensors)
write (*,*) out_data(:)

! Cleanup
call torch_module_delete(model)
call torch_model_delete(model)
call torch_tensor_delete(in_tensors(1))
call torch_tensor_delete(out_tensors(1))

Expand Down
12 changes: 6 additions & 6 deletions examples/2_ResNet18/resnet_infer_fortran.f90
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ subroutine main()
character(len=128), dimension(:), allocatable :: args

! Set up types of input and output data
type(torch_module) :: model
type(torch_model) :: model
type(torch_tensor), dimension(1) :: in_tensors
type(torch_tensor), dimension(1) :: out_tensors

Expand Down Expand Up @@ -76,15 +76,15 @@ subroutine main()
call load_data(filename, tensor_length, in_data)

! Create input/output tensors from the above arrays
in_tensors(1) = torch_tensor_from_array(in_data, in_layout, torch_kCPU)
call torch_tensor_from_array(in_tensors(1), in_data, in_layout, torch_kCPU)

out_tensors(1) = torch_tensor_from_array(out_data, out_layout, torch_kCPU)
call torch_tensor_from_array(out_tensors(1), out_data, out_layout, torch_kCPU)

! Load ML model (edit this line to use different models)
model = torch_module_load(args(1))
call torch_model_load(model, args(1))

! Infer
call torch_module_forward(model, in_tensors, out_tensors)
call torch_model_forward(model, in_tensors, out_tensors)

! Load categories
call load_categories(filename_cats, N_cats, categories)
Expand All @@ -102,7 +102,7 @@ subroutine main()
write (*,*) trim(categories(idx(2))), " (id=", idx(2), "), : probability =", probability

! Cleanup
call torch_module_delete(model)
call torch_model_delete(model)
call torch_tensor_delete(in_tensors(1))
call torch_tensor_delete(out_tensors(1))
deallocate(in_data)
Expand Down
18 changes: 9 additions & 9 deletions examples/3_MultiGPU/simplenet_infer_fortran.f90
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ program inference
integer :: tensor_layout(1) = [1]

! Set up Torch data structures
type(torch_module) :: model
type(torch_model) :: model
type(torch_tensor), dimension(1) :: in_tensors
type(torch_tensor) :: out_tensor
type(torch_tensor), dimension(1) :: out_tensors

! MPI configuration
integer :: rank, ierr, i
Expand All @@ -48,30 +48,30 @@ program inference
! Create Torch input tensor from the above array and assign it to the first (and only)
! element in the array of input tensors.
! We use the torch_kCUDA device type with device index corresponding to the MPI rank.
in_tensors(1) = torch_tensor_from_array(in_data, tensor_layout, torch_kCUDA, &
device_index=rank)
call torch_tensor_from_array(in_tensors(1), in_data, tensor_layout, &
torch_kCUDA, device_index=rank)

! Create Torch output tensor from the above array.
! Here we use the torch_kCPU device type since the tensor is for output only
! i.e. to be subsequently used by Fortran on CPU.
out_tensor = torch_tensor_from_array(out_data, tensor_layout, torch_kCPU)
call torch_tensor_from_array(out_tensors(1), out_data, tensor_layout, torch_kCPU)

! Load ML model. Ensure that the same device type and device index are used
! as for the input data.
model = torch_module_load(args(1), device_type=torch_kCUDA, &
call torch_model_load(model, args(1), device_type=torch_kCUDA, &
device_index=rank)

! Infer
call torch_module_forward(model, in_tensors, out_tensor)
call torch_model_forward(model, in_tensors, out_tensors)

! Print the values computed on each MPI rank.
write (6, 200) rank, out_data(:)
200 format("output on rank ", i1,": [", 4(f5.1,","), f5.1,"]")

! Cleanup
call torch_module_delete(model)
call torch_model_delete(model)
call torch_tensor_delete(in_tensors(1))
call torch_tensor_delete(out_tensor)
call torch_tensor_delete(out_tensors(1))
call mpi_finalize(ierr)

end program inference
16 changes: 8 additions & 8 deletions examples/4_MultiIO/multiionet_infer_fortran.f90
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ program inference

! Set up Torch data structures
! The net, a vector of input tensors (in this case we only have one), and the output tensor
type(torch_module) :: model
type(torch_model) :: model
type(torch_tensor), dimension(2) :: in_tensors
type(torch_tensor), dimension(2) :: out_tensors

Expand All @@ -39,21 +39,21 @@ program inference
in_data2(:) = [0.0, -1.0, -2.0, -3.0]

! Create Torch input/output tensors from the above arrays
in_tensors(1) = torch_tensor_from_array(in_data1, tensor_layout, torch_kCPU)
in_tensors(2) = torch_tensor_from_array(in_data2, tensor_layout, torch_kCPU)
out_tensors(1) = torch_tensor_from_array(out_data1, tensor_layout, torch_kCPU)
out_tensors(2) = torch_tensor_from_array(out_data2, tensor_layout, torch_kCPU)
call torch_tensor_from_array(in_tensors(1), in_data1, tensor_layout, torch_kCPU)
call torch_tensor_from_array(in_tensors(2), in_data2, tensor_layout, torch_kCPU)
call torch_tensor_from_array(out_tensors(1), out_data1, tensor_layout, torch_kCPU)
call torch_tensor_from_array(out_tensors(2), out_data2, tensor_layout, torch_kCPU)

! Load ML model
model = torch_module_load(args(1))
call torch_model_load(model, args(1))

! Infer
call torch_module_forward(model, in_tensors, out_tensors)
call torch_model_forward(model, in_tensors, out_tensors)
write (*,*) out_data1
write (*,*) out_data2

! Cleanup
call torch_module_delete(model)
call torch_model_delete(model)
call torch_tensor_delete(in_tensors(1))
call torch_tensor_delete(in_tensors(2))
call torch_tensor_delete(out_tensors(1))
Expand Down
14 changes: 7 additions & 7 deletions pages/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ use ftorch
implicit none
! Generate an object to hold the Torch model
type(torch_module) :: model
type(torch_model) :: model
! Set up array of n_inputs input tensors and array of n_outputs output tensors
! Note: In this example there is only one input tensor (n_inputs = 1) and one
Expand All @@ -70,26 +70,26 @@ integer, parameter :: out_dims = 1
integer :: out_layout(out_dims) = [1]
! Initialise the Torch model to be used
model = torch_module_load("/path/to/saved/model.pt")
torch_model_load(model, "/path/to/saved/model.pt")
! Initialise the inputs as Fortran array of ones
input = 1.0
! Wrap Fortran data as no-copy Torch Tensors
! There may well be some reshaping required depending on the
! structure of the model which is not covered here (see examples)
model_input_arr(1) = torch_tensor_from_array(input, in_layout, torch_kCPU)
model_output_arr(1) = torch_tensor_from_array(output, out_layout, torch_kCPU)
call torch_tensor_from_array(model_input_arr(1), input, in_layout, torch_kCPU)
call torch_tensor_from_array(model_output_arr(1), output, out_layout, torch_kCPU)
! Run model and Infer
! Run model forward method and Infer
! Again, there may be some reshaping required depending on model design
call torch_module_forward(model, model_input_arr, model_output_arr)
call torch_model_forward(model, model_input_arr, model_output_arr)
! Write out the result of running the model
write(*,*) output
! Clean up
call torch_module_delete(model)
call torch_model_delete(model)
call torch_tensor_delete(model_input_arr(1))
call torch_tensor_delete(model_output_arr(1))
```
Expand Down
7 changes: 4 additions & 3 deletions pages/gpu.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,15 @@ For example, the following code snippet sets up a Torch tensor with GPU device i

```fortran
device_index = 2
in_tensors(1) = torch_tensor_from_array(in_data, tensor_layout, torch_kCUDA, &
device_index=device_index)
call torch_tensor_from_array(in_tensors(1), in_data, tensor_layout, &
torch_kCUDA, device_index=device_index)
```

Whereas the following code snippet sets up a Torch tensor with (default) device index 0:

```fortran
in_tensors(1) = torch_tensor_from_array(in_data, tensor_layout, torch_kCUDA)
call torch_tensor_from_array(in_tensors(1), in_data, tensor_layout, &
torch_kCUDA)
```

See the
Expand Down
4 changes: 2 additions & 2 deletions pages/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ on locating Torch within a virtual environment (venv) for CMake.

### Why are inputs to torch models an array?

The reason input and output tensors to [[torch_module_forward(subroutine)]] are
The reason input and output tensors to [[torch_model_forward(subroutine)]] are
contained in arrays is because it is possible to pass multiple input tensors to
the `forward()` method of a torch net, and it is possible for the net to return
multiple output arrays.<br>
The nature of Fortran means that it is not possible to set an arbitrary number
of inputs to the `torch_module_forward` subroutine, so instead we use a single
of inputs to the `torch_model_forward` subroutine, so instead we use a single
array of input tensors which _can_ have an arbitrary length. Similarly, a single
array of output tensors is used.

Expand Down
Loading

0 comments on commit e92ad9e

Please sign in to comment.