Import a network from ONNX JSON format.
The parser keeps section-specific state in small helper types so the main procedure only coordinates file I/O and dispatch.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | file |
File to import the network from |
||
| integer, | intent(in), | optional | :: | verbose |
Verbosity level |
Resulting network instance
module function read_onnx(file, verbose) result(network) !! Import a network from ONNX JSON format. !! !! The parser keeps section-specific state in small helper types so the !! main procedure only coordinates file I/O and dispatch. implicit none ! Arguments character(*), intent(in) :: file !! File to import the network from integer, intent(in), optional :: verbose !! Verbosity level type(network_type) :: network !! Resulting network instance ! Local variables integer :: unit, stat, verbose_ !! File unit, I/O status and effective verbosity character(131072) :: line !! File input buffer sized for large base64-encoded initialisers character(:), allocatable :: trimmed !! Current input line with leading and trailing whitespace removed type(json_parse_result_type) :: parsed !! Parsed ONNX records collected across all sections type(json_parser_state_type) :: parser !! Section-specific parser state logical :: has_gnn !! Whether the parsed model contains ATHENA GNN metadata !-------------------------------------------------------------------------- ! Initialise options and parser state !-------------------------------------------------------------------------- if(present(verbose))then verbose_ = verbose else verbose_ = 0 end if call initialise_json_parser(parser) !-------------------------------------------------------------------------- ! Read and dispatch JSON lines !-------------------------------------------------------------------------- open(newunit=unit, file=file, status='old', action='read', iostat=stat) if(stat .ne. 0)then write(*,*) 'ERROR: Could not open file: ', trim(file) return end if do read(unit, '(A)', iostat=stat) line if(stat .ne. 0) exit trimmed = trim(adjustl(line)) if(len_trim(trimmed) .eq. 0) cycle call detect_json_section(trimmed, parser) select case(trim(parser%section)) case('node') call parse_node_section_line(trimmed, parser%node, parsed, & parser%section) case('initializer') call parse_initialiser_section_line(trimmed, parser%initialiser, & parsed, parser%section) case('input') call parse_tensor_section_line(trimmed, parser%input_tensor, & parsed%inputs, parsed%num_inputs, parser%section) case('output') call parse_tensor_section_line(trimmed, parser%output_tensor, & parsed%outputs, parsed%num_outputs, parser%section) case('metadata') call parse_metadata_line(trimmed, parsed, parser%section) end select end do close(unit) if(verbose_ .gt. 0)then write(*,*) 'JSON parse: ', parsed%num_nodes, ' nodes, ', & parsed%num_inits, ' initialisers, ', parsed%num_inputs, & ' inputs, ', parsed%num_outputs, ' outputs, ', & parsed%num_meta, ' metadata' end if !-------------------------------------------------------------------------- ! Build the ATHENA network from the parsed JSON records !-------------------------------------------------------------------------- has_gnn = parsed%num_meta .gt. 0 if(has_gnn)then call build_network_from_json_gnn( & network, parsed%nodes, parsed%num_nodes, & parsed%inits, parsed%num_inits, & parsed%inputs, parsed%num_inputs, & parsed%outputs, parsed%num_outputs, & parsed%meta_keys, parsed%meta_values, parsed%num_meta, & verbose_) else call build_network_from_json_standard( & network, parsed%nodes, parsed%num_nodes, & parsed%inits, parsed%num_inits, & parsed%inputs, parsed%num_inputs, verbose_) end if end function read_onnx