From 694916832c49bbbe9f526c5a5a38aba9a2603783 Mon Sep 17 00:00:00 2001 From: Grim Maple Date: Fri, 24 Apr 2020 00:18:10 +0300 Subject: [PATCH 1/2] Fix deserialization on Windows --- src/vectorflow/serde.d | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/vectorflow/serde.d b/src/vectorflow/serde.d index 66c238f..607252c 100644 --- a/src/vectorflow/serde.d +++ b/src/vectorflow/serde.d @@ -52,14 +52,32 @@ class Serializer { final T read(T)() if(isSomeString!T || isBasicType!T || isUnsigned!T) { scope(failure){ if(_f.eof) throw new EOFException("");} - scope(exit){ if(_f.eof) throw new EOFException("");} + version(Windows){} // Windows requires special treatment with EOF + else scope(exit){ if(_f.eof) throw new EOFException(""); } static if(isSomeString!T) { - ulong str_sz; - _f.rawRead((&str_sz)[0..1]); - auto str = new ubyte[str_sz.to!size_t]; - str = _f.rawRead(str); - return cast(string)str; + // On Windows EOF is not set before you try to read past the end, so it requires some special handling + // Original code was causing runtime crashes rendering deserialization impossible. + // If we use more low level approach and manually throw EOFException if we can't read elemnts it works. + version(Windows) + { + import core.stdc.stdio : fread; + ulong str_sz; + auto sz = fread(&str_sz, str_sz.sizeof, 1, _f.getFP); + if(sz < 1) throw new EOFException(""); + auto str = new ubyte[str_sz.to!size_t]; + sz = fread(str.ptr, ubyte.sizeof, str_sz, _f.getFP); + if(sz < str_sz) throw new EOFException(""); + return cast(string)str; + } + else + { + ulong str_sz; + _f.rawRead((&str_sz)[0..1]); + auto str = new ubyte[str_sz.to!size_t]; + str = _f.rawRead(str); + return cast(string)str; + } } else { From e560c09fffb97cb64f7e5b09bf89b85f9d16dd2f Mon Sep 17 00:00:00 2001 From: Grim Date: Thu, 2 May 2024 21:52:17 +0300 Subject: [PATCH 2/2] Prevent writes --- src/vectorflow/neuralnet.d | 8 ++++---- src/vectorflow/serde.d | 2 +- test/common.d | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vectorflow/neuralnet.d b/src/vectorflow/neuralnet.d index 03f1e01..0e761ed 100644 --- a/src/vectorflow/neuralnet.d +++ b/src/vectorflow/neuralnet.d @@ -432,7 +432,7 @@ class NeuralNet { if(!_ever_initialized) { - writeln("Net not initialized. Initializing all weights to 0."); + version(VectorflowPrint) writeln("Net not initialized. Initializing all weights to 0."); initialize(0.0); } { @@ -458,7 +458,7 @@ class NeuralNet { auto cores_str = ( num_cores == 1 ? "1 core." : "%d cores.".format(num_cores)); - writeln("Training net with ", num_params, " parameters on ", cores_str); + version(VectorflowPrint) writeln("Training net with ", num_params, " parameters on ", cores_str); foreach(l; layers) l.pre_learning(); opt.learn(this, data, grad_f, verbose, num_cores); @@ -597,12 +597,12 @@ class NeuralNet { f.close(); try { - writeln("Serialization failed."); + version(VectorflowPrint) writeln("Serialization failed."); remove(path); } catch(FileException e) { - writeln("Couldn't cleanup `", path, + version(VectorflowPrint) writeln("Couldn't cleanup `", path, "` after serialization failure: ", e); } } diff --git a/src/vectorflow/serde.d b/src/vectorflow/serde.d index 607252c..3cfa021 100644 --- a/src/vectorflow/serde.d +++ b/src/vectorflow/serde.d @@ -117,7 +117,7 @@ class Serializer { auto l = Object.factory(layer_type).to!NeuralLayer; l.deser(this); layers ~= l; - writeln("Deserialized ", l.to!string); + version(VectorflowPrint) writeln("Deserialized ", l.to!string); } return layers; diff --git a/test/common.d b/test/common.d index 0b9de3f..6f149ea 100644 --- a/test/common.d +++ b/test/common.d @@ -107,12 +107,12 @@ version(unittest) } } } - writeln("----------"); + version(VectorflowPrint) writeln("----------"); if(failed > 0) { - writefln("At least %d test(s) failed.", failed); + version(VectorflowPrint) writefln("At least %d test(s) failed.", failed); foreach(m; retro(messages)) - writeln(m); + version(VectorflowPrint) writeln(m); } return failed == 0; }