123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899(**************************************************************************)(* *)(* This file is part of CAISAR. *)(* *)(* Copyright (C) 2022 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* *)(* You can redistribute it and/or modify it under the terms of the GNU *)(* Lesser General Public License as published by the Free Software *)(* Foundation, version 2.1. *)(* *)(* It is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file licenses/LGPLv2.1). *)(* *)(**************************************************************************)openBasemoduleFormat=Caml.FormatmoduleSys=Caml.SysmoduleFilename=Caml.FilenamemoduleFun=Caml.Funtypet={n_inputs:int;n_outputs:int}(* OVO format handling. *)letovo_format_errors=Error(Format.sprintf"OVO format error: %s condition not satisfied."s)(* Parse a single OVO format line: split line wrt CSV format, and convert each
string into a number by means of converter [f]. *)lethandle_ovo_line~fin_channel=List.filter_map~f:(funs->trySome(f(String.strips))with_->None)(Csv.nextin_channel)(* Skip the header part, ie comments, of the OVO format. *)letskip_ovo_headerfilenamein_channel=letexceptionEnd_of_headerinletpos_in=ref(Stdlib.pos_inin_channel)intrywhiletruedoletline=Stdlib.input_linein_channelinifnot(Str.string_match(Str.regexp"//")line0)thenraiseEnd_of_headerelsepos_in:=Stdlib.pos_inin_channeldone;assertfalsewith|End_of_header->(* At this point we have read one line past the header part: seek back. *)Stdlib.seek_inin_channel!pos_in;Ok()|End_of_file->Error(Format.sprintf"OVO model not found in file `%s'."filename)(* Retrieve inputs and outputs size. *)lethandle_ovo_basic_infoin_channel=matchhandle_ovo_line~f:Int.of_stringin_channelwith|[dim]->Okdim|_->ovo_format_error"first"|exceptionEnd_of_file->ovo_format_error"first"(* Skip unused flag. *)lethandle_ovo_unused_flagin_channel=trylet_=Csv.nextin_channelinOk()withEnd_of_file->ovo_format_error"second"(* Retrieves [filename] OVO model metadata and weights wrt OVO format
specification, which is described here:
https://github.com/abstract-machine-learning/saver#classifier-format. *)letparse_in_channelfilenamein_channel=letopenResultintryskip_ovo_headerfilenamein_channel>>=fun()->letin_channel=Csv.of_channelin_channelinhandle_ovo_unused_flagin_channel>>=fun()->handle_ovo_basic_infoin_channel>>=funn_is->handle_ovo_basic_infoin_channel>>=funn_os->Csv.close_inin_channel;Ok{n_inputs=n_is;n_outputs=n_os}with|Csv.Failure(_nrecord,_nfield,msg)->Errormsg|Sys_errors->Errors|Failuremsg->Error(Format.sprintf"Unexpected error: %s."msg)letparsefilename=letin_channel=Stdlib.open_infilenameinFun.protect~finally:(fun()->Stdlib.close_inin_channel)(fun()->parse_in_channelfilenamein_channel)