Build JSON string for layer attributes
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(base_layer_type), | intent(in) | :: | layer |
Layer supplying ONNX attribute metadata |
||
| character(len=*), | intent(in) | :: | op_type |
ONNX operation type used to handle special cases |
||
| character(len=4096), | intent(out) | :: | attr_json |
Serialized JSON fragment containing the emitted attributes |
subroutine build_attributes_json(layer, op_type, attr_json) !! Build JSON string for layer attributes implicit none ! Arguments class(base_layer_type), intent(in) :: layer !! Layer supplying ONNX attribute metadata character(*), intent(in) :: op_type !! ONNX operation type used to handle special cases character(4096), intent(out) :: attr_json !! Serialized JSON fragment containing the emitted attributes ! Local variables type(onnx_attribute_type), allocatable, dimension(:) :: attributes !! Attribute list returned by the layer integer :: i, j, itmp1 !! Attribute index, value index, and temporary integer count character(256) :: buffer !! Temporary string buffer for serialised scalar values integer, allocatable :: ivar_list(:) !! Parsed integer attribute payload for INTS-valued attributes real(real32), allocatable :: rvar_list(:) !! Placeholder for future real-valued list attributes character(10) :: type_lw !! Lower-case attribute type string used in the select case attr_json = '' ! For Gemm, add transB attribute if(trim(op_type) .eq. 'Gemm')then attr_json = ' "attribute": [' // & '{"name": "alpha", "f": 1.0, "type": "FLOAT"}, ' // & '{"name": "beta", "f": 1.0, "type": "FLOAT"}, ' // & '{"name": "transB", "i": "1", "type": "INT"}]' return end if attributes = layer%get_attributes() if(.not.allocated(attributes) .or. size(attributes) .eq. 0) return attr_json = ' "attribute": [' do i = 1, size(attributes) if(i .gt. 1) attr_json = trim(attr_json) // ', ' attr_json = trim(attr_json) // '{"name": "' // & trim(attributes(i)%name) // '"' type_lw = trim(adjustl(attributes(i)%type)) select case(type_lw) case('int') attr_json = trim(attr_json) // ', "i": "' // & trim(adjustl(attributes(i)%val)) // '", "type": "INT"}' case('ints') ! Parse multiple ints itmp1 = 1 do j = 1, len_trim(attributes(i)%val) if(attributes(i)%val(j:j) .eq. ' ') itmp1 = itmp1 + 1 end do allocate(ivar_list(itmp1)) read(attributes(i)%val, *) ivar_list attr_json = trim(attr_json) // ', "ints": [' do j = 1, itmp1 if(j .gt. 1) attr_json = trim(attr_json) // ', ' write(buffer, '("""",I0,"""")') ivar_list(j) attr_json = trim(attr_json) // trim(adjustl(buffer)) end do attr_json = trim(attr_json) // '], "type": "INTS"}' deallocate(ivar_list) case('float') attr_json = trim(attr_json) // ', "f": ' // & trim(adjustl(attributes(i)%val)) // ', "type": "FLOAT"}' case('string') ! Base64 encode the string value call encode_string_base64( & trim(adjustl(attributes(i)%val)), buffer) attr_json = trim(attr_json) // ', "s": "' // & trim(buffer) // '", "type": "STRING"}' case default attr_json = trim(attr_json) // '}' end select end do attr_json = trim(attr_json) // ']' end subroutine build_attributes_json