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 66c238f..3cfa021 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 { @@ -99,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; }