Read the message passing layer
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(kipf_msgpass_layer_type), | intent(inout) | :: | this |
Instance of the message passing layer |
||
| integer, | intent(in) | :: | unit |
Unit to read from |
||
| integer, | intent(in), | optional | :: | verbose |
Verbosity level |
subroutine read_kipf(this, unit, verbose) !! Read the message passing layer use athena__tools_infile, only: assign_val, assign_vec, get_val, move use coreutils, only: to_lower, to_upper, icount use athena__activation, only: read_activation use athena__initialiser, only: initialiser_setup implicit none ! Arguments class(kipf_msgpass_layer_type), intent(inout) :: this !! Instance of the message passing layer integer, intent(in) :: unit !! Unit to read from integer, optional, intent(in) :: verbose !! Verbosity level ! Local variables integer :: stat !! Status of read integer :: verbose_ = 0 !! Verbosity level integer :: t, j, k, c, itmp1, iline !! Loop variables and temporary integer integer :: num_time_steps = 0 !! Number of time steps character(14) :: kernel_initialiser_name='' !! Initialisers character(20) :: activation_name='' !! Activation function name class(base_actv_type), allocatable :: activation !! Activation function class(base_init_type), allocatable :: kernel_initialiser !! Initialisers integer, dimension(:), allocatable :: num_vertex_features !! Number of vertex and edge features character(256) :: buffer, tag, err_msg !! Buffer, tag, and error message real(real32), allocatable, dimension(:) :: data_list !! Data list integer :: param_line, final_line !! Parameter line number ! Initialise optional arguments !--------------------------------------------------------------------------- if(present(verbose)) verbose_ = verbose ! Loop over tags in layer card !--------------------------------------------------------------------------- iline = 0 param_line = 0 final_line = 0 tag_loop: do ! Check for end of file !------------------------------------------------------------------------ read(unit,'(A)',iostat=stat) buffer if(stat.ne.0)then write(err_msg,'("file encountered error (EoF?) before END ",A)') & to_upper(this%name) call stop_program(err_msg) return end if if(trim(adjustl(buffer)).eq."") cycle tag_loop ! Check for end of layer card !------------------------------------------------------------------------ if(trim(adjustl(buffer)).eq."END "//to_upper(trim(this%name)))then final_line = iline backspace(unit) exit tag_loop end if iline = iline + 1 tag=trim(adjustl(buffer)) if(scan(buffer,"=").ne.0) tag=trim(tag(:scan(tag,"=")-1)) ! Read parameters from file !------------------------------------------------------------------------ select case(trim(tag)) case("NUM_TIME_STEPS") call assign_val(buffer, num_time_steps, itmp1) case("NUM_VERTEX_FEATURES") itmp1 = icount(get_val(buffer)) allocate(num_vertex_features(itmp1), source=0) call assign_vec(buffer, num_vertex_features, itmp1) case("ACTIVATION") iline = iline - 1 backspace(unit) activation = read_activation(unit, iline) case("KERNEL_INITIALISER", "KERNEL_INIT", "KERNEL_INITIALisER") call assign_val(buffer, kernel_initialiser_name, itmp1) case("WEIGHTS") kernel_initialiser_name = 'zeros' param_line = iline case default ! Don't look for "e" due to scientific notation of numbers ! ... i.e. exponent (E+00) if(scan(to_lower(trim(adjustl(buffer))),& 'abcdfghijklmnopqrstuvwxyz').eq.0)then cycle tag_loop elseif(tag(:3).eq.'END')then cycle tag_loop end if write(err_msg,'("Unrecognised line in input file: ",A)') & trim(adjustl(buffer)) call stop_program(err_msg) return end select end do tag_loop kernel_initialiser = initialiser_setup(kernel_initialiser_name) ! Set hyperparameters and initialise layer !--------------------------------------------------------------------------- if(num_time_steps.gt.0 .and. num_time_steps.ne.size(num_vertex_features,1)-1)then write(err_msg,'("NUM_TIME_STEPS = ",I0," does not match length of "// & &"NUM_VERTEX_FEATURES = ",I0)') num_time_steps, & size(num_vertex_features,1)-1 call stop_program(err_msg) return end if call this%set_hyperparams( & num_time_steps = num_time_steps, & num_vertex_features = num_vertex_features, & activation = activation, & kernel_initialiser = kernel_initialiser, & verbose = verbose_ & ) call this%init(input_shape=[this%num_vertex_features(0), 0]) ! Check if WEIGHTS card was found !--------------------------------------------------------------------------- if(param_line.eq.0)then write(0,*) "WARNING: WEIGHTS card in "//to_upper(trim(this%name))//" not found" else call move(unit, param_line - iline, iostat=stat) do t = 1, this%num_time_steps allocate(data_list(this%num_params_msg(t)), source=0._real32) c = 1 k = 1 data_concat_loop: do while(c.le.this%num_params_msg(t)) read(unit,'(A)',iostat=stat) buffer if(stat.ne.0) exit data_concat_loop k = icount(buffer) read(buffer,*,iostat=stat) (data_list(j),j=c,c+k-1) c = c + k end do data_concat_loop this%params(t)%val(:,1) = data_list(1:this%num_params_msg(t)) deallocate(data_list) end do ! Check for end of weights card !------------------------------------------------------------------------ read(unit,'(A)') buffer if(trim(adjustl(buffer)).ne."END WEIGHTS")then write(0,*) trim(adjustl(buffer)) call stop_program("END WEIGHTS not where expected") return end if end if !--------------------------------------------------------------------------- ! Check for end of layer card !--------------------------------------------------------------------------- read(unit,'(A)') buffer if(trim(adjustl(buffer)).ne."END "//to_upper(trim(this%name)))then write(0,*) trim(adjustl(buffer)) write(err_msg,'("END ",A," not where expected")') to_upper(this%name) call stop_program(err_msg) return end if end subroutine read_kipf