Build network from ONNX nodes and initialisers
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(network_type), | intent(inout) | :: | this |
Instance of network |
||
| type(onnx_node_type), | intent(in), | dimension(:) | :: | nodes |
Array of ONNX nodes |
|
| type(onnx_initialiser_type), | intent(in), | dimension(:) | :: | initialisers |
Array of ONNX initialisers |
|
| type(onnx_tensor_type), | intent(in), | dimension(:) | :: | inputs |
Array of ONNX inputs |
|
| type(onnx_tensor_type), | intent(in), | dimension(:) | :: | value_info |
Array of ONNX value infos |
|
| integer, | intent(in), | optional | :: | verbose |
Verbosity level |
module subroutine build_from_onnx( & this, nodes, initialisers, inputs, value_info, verbose & ) !! Build network from ONNX nodes and initialisers use coreutils, only: to_lower implicit none ! Arguments class(network_type), intent(inout) :: this !! Instance of network type(onnx_node_type), dimension(:), intent(in) :: nodes !! Array of ONNX nodes type(onnx_initialiser_type), dimension(:), intent(in) :: initialisers !! Array of ONNX initialisers type(onnx_tensor_type), dimension(:), intent(in) :: inputs !! Array of ONNX inputs type(onnx_tensor_type), dimension(:), intent(in) :: value_info !! Array of ONNX value infos integer, optional, intent(in) :: verbose !! Verbosity level ! Local variables integer :: i, j, k, j_out, layer_index !! Loop indices integer :: verbose_ = 0 !! Verbosity level character(20) :: op_type !! Lowercase op_type character(64) :: tmp_name !! Temporary name for matching character(256) :: err_msg !! Error message integer, dimension(:), allocatable :: input_shape !! Shape of input layer integer, dimension(:), allocatable :: input_list !! List of input layers type(onnx_initialiser_type), dimension(:), allocatable :: init_list !! List of initialisers for a specific node type(onnx_tensor_type), dimension(:), allocatable :: value_info_list !! List of value info tensors verbose_ = 0 if(present(verbose)) verbose_ = verbose if(.not.allocated(list_of_onnx_layer_creators))then call allocate_list_of_onnx_layer_creators() end if do i = 1, size(inputs) input_shape = inputs(i)%dims(2:size(inputs(i)%dims)) call this%add( & input_layer_type(input_shape, index=i) & ) end do ! Loop through nodes and create layers do i = 1, size(nodes) if(verbose_.gt.0) write(*,*) "Processing ONNX node: ", trim(nodes(i)%name), & " (", trim(nodes(i)%op_type), ")" op_type = trim(adjustl(nodes(i)%op_type)) layer_index = & findloc( & [ list_of_onnx_layer_creators(:)%op_type ], & op_type, & dim = 1 & ) if(layer_index.eq.0)then write(err_msg,'("unrecognised op_type ''",A)') trim(adjustl(nodes(i)%op_type)) call stop_program(err_msg) return end if ! find all input layers and initialisers for this node ! ... i.e. check over inputs for name matches j_out = 0 allocate(init_list(0)) allocate(input_list(0)) allocate(value_info_list(0)) do j = 1, size(nodes(i)%inputs) do k = 1, size(initialisers) if(trim(nodes(i)%inputs(j)) .eq. trim(initialisers(k)%name))then init_list = [ init_list, initialisers(k) ] end if end do do k = 1, size(inputs) if(trim(nodes(i)%inputs(j)) .eq. trim(inputs(k)%name))then input_list = [ input_list, k ] end if end do tmp_name = trim(nodes(i)%inputs(j)) if(index(tmp_name, "_output").gt.0) & tmp_name = trim(tmp_name(:index(tmp_name, "_output")-1)) do k = 1, size(nodes) if(trim(tmp_name) .eq. trim(nodes(k)%name))then input_list = [ input_list, k + size(inputs) ] end if end do end do do j = 1, size(nodes(i)%outputs) do k = 1, size(value_info) if(trim(nodes(i)%outputs(j)) .eq. trim(value_info(k)%name))then value_info_list = [ value_info_list, value_info(k) ] end if end do end do if(size(init_list)+size(input_list).ne.size(nodes(i)%inputs))then if(verbose_.gt.0)then write(0,*) "WARNING: not all inputs found for node ", & trim(nodes(i)%name) end if end if ! assume default operator call this%add( & list_of_onnx_layer_creators(layer_index)%create_ptr( & nodes(i), init_list, value_info_list & ), & input_list = input_list & ! operator = operator_in & ) deallocate(input_list) deallocate(init_list) deallocate(value_info_list) end do if(verbose_.gt.0) write(*,*) "ONNX model built with ", this%num_layers, " layers." end subroutine build_from_onnx