• Re: Is there a way to wait for WRITE?

    From Thomas Koenig@21:1/5 to James Van Buskirk on Sun Nov 13 08:55:51 2022
    James Van Buskirk <not_valid@comcast.net> schrieb:
    OK, I made some progress in my hobby project and now it
    displays a graph of its results. I put a READ(*,'(a)') statement
    at the end so my graphs wouldn't go away when the
    program terminates.

    After considerable effort I found out how to write a *.ppm
    file and how to get gimp.exe to convert all of my *.ppm
    files (which most software can't read) to *.png.

    You can also use the pngtopng command from netpbm, which
    is a bit more lightweight than gimp :-)

    Then I wrote a *.bat file that permits me to run a bunch
    of scenarios. Since I didn't want to have to change focus
    to the CMD.exe window and hit <ENTER> for every run
    of the program, I had it detect when it was running in batch
    mode and skip the READ(*,'(a)') statement because the
    graphs would be available in *.png form anyway.

    However, this caused a problem because the last and of
    course most important *.ppm doesn't complete writing
    before its thread closes,

    Do you do different threads in a main program? If
    so, how? OpenMP? Coarrays? pthreads? Windows
    threads?

    Or did you just mean program?

    so I don't get that *.ppm file.
    I tried putting a FLUSH(iunit) statement before the
    CLOSE(iunit) statement, but still no joy. How am I
    supposed to tell the thread to wait for the *.ppm file
    to get properly written and saved before returning?

    This is very hard to answer without knowing exactly what
    you did, what system (I presume Windows), and what
    thread model and what compiler you used.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to All on Sun Nov 13 01:46:36 2022
    OK, I made some progress in my hobby project and now it
    displays a graph of its results. I put a READ(*,'(a)') statement
    at the end so my graphs wouldn't go away when the
    program terminates.

    After considerable effort I found out how to write a *.ppm
    file and how to get gimp.exe to convert all of my *.ppm
    files (which most software can't read) to *.png.

    Then I wrote a *.bat file that permits me to run a bunch
    of scenarios. Since I didn't want to have to change focus
    to the CMD.exe window and hit <ENTER> for every run
    of the program, I had it detect when it was running in batch
    mode and skip the READ(*,'(a)') statement because the
    graphs would be available in *.png form anyway.

    However, this caused a problem because the last and of
    course most important *.ppm doesn't complete writing
    before its thread closes, so I don't get that *.ppm file.
    I tried putting a FLUSH(iunit) statement before the
    CLOSE(iunit) statement, but still no joy. How am I
    supposed to tell the thread to wait for the *.ppm file
    to get properly written and saved before returning?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to Thomas Koenig on Sun Nov 13 03:02:54 2022
    "Thomas Koenig" wrote in message news:tkqben$38a5n$1@newsreader4.netcologne.de...

    James Van Buskirk <not_valid@comcast.net> schrieb:
    OK, I made some progress in my hobby project and now it
    displays a graph of its results. I put a READ(*,'(a)') statement
    at the end so my graphs wouldn't go away when the
    program terminates.

    After considerable effort I found out how to write a *.ppm
    file and how to get gimp.exe to convert all of my *.ppm
    files (which most software can't read) to *.png.

    You can also use the pngtopng command from netpbm, which
    is a bit more lightweight than gimp :-)

    Well, I installed gimp for a previous project and its licensing
    arrangements seemed satisfactory. It's a bitch to use it in
    batch mode, though. What would have been really cool
    would have been a printer driver that had the option to
    print to file with *.png being one of the accessible formats.
    Then I could have rendered to the file like I have rendered
    to printer previously. However, Windows doesn't come with
    such goodies: Microsoft XPS Document Writer seems to be
    able to embed a PNG in a *.oxps file, but I couldn't figure
    out how to extract it from there. There are drivers out
    there on the web that can print to *.png, but using them
    would mean the my program wouldn't be self-contained.

    Then I wrote a *.bat file that permits me to run a bunch
    of scenarios. Since I didn't want to have to change focus
    to the CMD.exe window and hit <ENTER> for every run
    of the program, I had it detect when it was running in batch
    mode and skip the READ(*,'(a)') statement because the
    graphs would be available in *.png form anyway.

    However, this caused a problem because the last and of
    course most important *.ppm doesn't complete writing
    before its thread closes,

    Do you do different threads in a main program? If
    so, how? OpenMP? Coarrays? pthreads? Windows
    threads?

    Or did you just mean program?

    No, Windows threads with _beginthreadex() and the
    whole 9 yards. I tried putting a WaitForSingleObject
    call before program termination, but it had no effect.
    Seemingly the thread (and my *.ppm file) were already
    long gone by that time.

    so I don't get that *.ppm file.
    I tried putting a FLUSH(iunit) statement before the
    CLOSE(iunit) statement, but still no joy. How am I
    supposed to tell the thread to wait for the *.ppm file
    to get properly written and saved before returning?

    This is very hard to answer without knowing exactly what
    you did, what system (I presume Windows), and what
    thread model and what compiler you used.

    D:\gfortran\james>gfortran -v
    Using built-in specs.
    COLLECT_GCC=gfortran
    COLLECT_LTO_WRAPPER=C:/Program\ Files/mingw64/bin/../libexec/gcc/x86_64-w64-ming
    w32/12.2.0/lto-wrapper.exe
    Target: x86_64-w64-mingw32
    Configured with:
    ../../../src/gcc-12.2.0/configure --host=x86_64-w64-mingw32 --b uild=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sys
    root=/c/buildroot/x86_64-1220-win32-seh-rt_v10-rev1/mingw64 --enable-host-shared
    --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdcxx-time =yes --enable-threads=win32 --enable-libgomp --enable-libatomic --enable-lto
    --e
    nable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-
    version-specific-runtime-libs --enable-libstdcxx-filesystem-ts=yes --disable-lib
    stdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disabl
    e-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system
    -zlib --with-gmp=/c/buildroot/prerequisites/x86_64-w64-mingw32-static --with-mpf
    r=/c/buildroot/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/buildroot/p
    rerequisites/x86_64-w64-mingw32-static --with-isl=/c/buildroot/prerequisites/x86
    _64-w64-mingw32-static --with-pkgversion='x86_64-win32-seh-rev1, Built by MinGW-
    W64 project' --with-bugurl=https://sourceforge.net/projects/mingw-w64 CFLAGS='-O
    2 -pipe -fno-ident -I/c/buildroot/x86_64-1220-win32-seh-rt_v10-rev1/mingw64/opt/
    include -I/c/buildroot/prerequisites/x86_64-zlib-static/include -I/c/buildroot/p
    rerequisites/x86_64-w64-mingw32-static/include'
    CXXFLAGS='-O2 -pipe -fno-ident - I/c/buildroot/x86_64-1220-win32-seh-rt_v10-rev1/mingw64/opt/include -I/c/buildro
    ot/prerequisites/x86_64-zlib-static/include -I/c/buildroot/prerequisites/x86_64-
    w64-mingw32-static/include'
    CPPFLAGS=' -I/c/buildroot/x86_64-1220-win32-seh-rt_v 10-rev1/mingw64/opt/include -I/c/buildroot/prerequisites/x86_64-zlib-static/incl
    ude -I/c/buildroot/prerequisites/x86_64-w64-mingw32-static/include' LDFLAGS='-pi
    pe -fno-ident -L/c/buildroot/x86_64-1220-win32-seh-rt_v10-rev1/mingw64/opt/lib
    -
    L/c/buildroot/prerequisites/x86_64-zlib-static/lib -L/c/buildroot/prerequisites/
    x86_64-w64-mingw32-static/lib ' LD_FOR_TARGET=/c/buildroot/x86_64-1220-win32-seh -rt_v10-rev1/mingw64/bin/ld.exe --with-boot-ldflags=' -Wl,--disable-dynamicbase -static-libstdc++ -static-libgcc'
    Thread model: win32
    Supported LTO compression algorithms: zlib
    gcc version 12.2.0 (x86_64-win32-seh-rev1, Built by MinGW-W64 project)


    As you can see, the compiler is using win32 threads rather than posix. I
    had
    difficulties early on so I downloaded this compiler although I am not sure
    if
    it is necessary to use the win32 threads gfortran compiler if you are making threads via the Win32 API.

    The program is kinda long: win.f90=33 kB, gl.f90=41 kB, xygraph.f90 = 58 kB
    and even my calculational engine is 47 kB. It definitely needs Windows to
    work and the ifort-compiled version just hangs without any output.
    Thus, it wouldn't do much good to post the code because nobody would
    have the time, energy, and ability to investigate it.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Spiros Bousbouras@21:1/5 to Thomas Koenig on Sun Nov 13 12:10:12 2022
    On Sun, 13 Nov 2022 11:24:21 -0000 (UTC)
    Thomas Koenig <tkoenig@netcologne.de> wrote:
    James Van Buskirk <not_valid@comcast.net> schrieb:
    "Thomas Koenig" wrote in message news:tkqben$38a5n$1@newsreader4.netcologne.de...

    James Van Buskirk <not_valid@comcast.net> schrieb:
    After considerable effort I found out how to write a *.ppm
    file and how to get gimp.exe to convert all of my *.ppm
    files (which most software can't read) to *.png.

    You can also use the pngtopng command from netpbm, which
    is a bit more lightweight than gimp :-)

    Well, I installed gimp for a previous project and its licensing arrangements seemed satisfactory. It's a bitch to use it in
    batch mode, though.

    That is what netpbm is for.

    You could just do

    CALL EXECUTE_COMMAND_LINE ("pngtopng yourfile.ppm > yourfile.png")

    from your Fortran program, this should work. It might open a
    cmd window, though.

    Is there a pngtopng programme ? Do you mean pnmtopng perhaps ?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Koenig@21:1/5 to James Van Buskirk on Sun Nov 13 11:24:21 2022
    James Van Buskirk <not_valid@comcast.net> schrieb:
    "Thomas Koenig" wrote in message news:tkqben$38a5n$1@newsreader4.netcologne.de...

    James Van Buskirk <not_valid@comcast.net> schrieb:
    OK, I made some progress in my hobby project and now it
    displays a graph of its results. I put a READ(*,'(a)') statement
    at the end so my graphs wouldn't go away when the
    program terminates.

    After considerable effort I found out how to write a *.ppm
    file and how to get gimp.exe to convert all of my *.ppm
    files (which most software can't read) to *.png.

    You can also use the pngtopng command from netpbm, which
    is a bit more lightweight than gimp :-)

    Well, I installed gimp for a previous project and its licensing
    arrangements seemed satisfactory. It's a bitch to use it in
    batch mode, though.

    That is what netpbm is for.

    You could just do

    CALL EXECUTE_COMMAND_LINE ("pngtopng yourfile.ppm > yourfile.png")

    from your Fortran program, this should work. It might open a
    cmd window, though.

    What would have been really cool
    would have been a printer driver that had the option to
    print to file with *.png being one of the accessible formats.
    Then I could have rendered to the file like I have rendered
    to printer previously. However, Windows doesn't come with
    such goodies: Microsoft XPS Document Writer seems to be
    able to embed a PNG in a *.oxps file, but I couldn't figure
    out how to extract it from there. There are drivers out
    there on the web that can print to *.png, but using them
    would mean the my program wouldn't be self-contained.

    Then I wrote a *.bat file that permits me to run a bunch
    of scenarios. Since I didn't want to have to change focus
    to the CMD.exe window and hit <ENTER> for every run
    of the program, I had it detect when it was running in batch
    mode and skip the READ(*,'(a)') statement because the
    graphs would be available in *.png form anyway.

    However, this caused a problem because the last and of
    course most important *.ppm doesn't complete writing
    before its thread closes,

    Do you do different threads in a main program? If
    so, how? OpenMP? Coarrays? pthreads? Windows
    threads?

    Or did you just mean program?

    No, Windows threads with _beginthreadex() and the
    whole 9 yards.

    OK, then I'm afraid I cannot really help you a lot. Just a couple
    of things:

    The gfortran runtime knows nothing about Windows threads. You have
    to make sure that there is no race condition etc. libgfortran
    locking is for pthreads only (which also works for gomp).

    If you are using threads, you will probably need -frecursive
    to make sure that all variables are on the stack.

    I tried putting a WaitForSingleObject
    call before program termination, but it had no effect.
    Seemingly the thread (and my *.ppm file) were already
    long gone by that time.

    If your thread exited (how did you do that?) it might
    have cleaned up after itself in some way, and left
    the runtime in an inconsistent state.

    The least you probably have to do is to make sure that any I/O
    library calls are only executed on a single thread, by putting
    the Windows equivalent of "omp critical" around it.

    so I don't get that *.ppm file.
    I tried putting a FLUSH(iunit) statement before the
    CLOSE(iunit) statement, but still no joy. How am I
    supposed to tell the thread to wait for the *.ppm file
    to get properly written and saved before returning?

    This is very hard to answer without knowing exactly what
    you did, what system (I presume Windows), and what
    thread model and what compiler you used.

    D:\gfortran\james>gfortran -v

    [...]

    As you can see, the compiler is using win32 threads rather than posix. I
    had
    difficulties early on so I downloaded this compiler although I am not sure
    if
    it is necessary to use the win32 threads gfortran compiler if you are making threads via the Win32 API.

    I have no idea about that, my systems programming fu is limited
    to UNIX.

    The program is kinda long: win.f90=33 kB, gl.f90=41 kB, xygraph.f90 = 58 kB and even my calculational engine is 47 kB. It definitely needs Windows to work and the ifort-compiled version just hangs without any output.
    Thus, it wouldn't do much good to post the code because nobody would
    have the time, energy, and ability to investigate it.

    If it's a hobby project, maybe you want to completely rewrite it in
    gtk-fortran :-)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Koenig@21:1/5 to Spiros Bousbouras on Sun Nov 13 12:50:47 2022
    Spiros Bousbouras <spibou@gmail.com> schrieb:
    On Sun, 13 Nov 2022 11:24:21 -0000 (UTC)
    Thomas Koenig <tkoenig@netcologne.de> wrote:
    James Van Buskirk <not_valid@comcast.net> schrieb:
    "Thomas Koenig" wrote in message
    news:tkqben$38a5n$1@newsreader4.netcologne.de...

    James Van Buskirk <not_valid@comcast.net> schrieb:
    After considerable effort I found out how to write a *.ppm
    file and how to get gimp.exe to convert all of my *.ppm
    files (which most software can't read) to *.png.

    You can also use the pngtopng command from netpbm, which
    is a bit more lightweight than gimp :-)

    Well, I installed gimp for a previous project and its licensing
    arrangements seemed satisfactory. It's a bitch to use it in
    batch mode, though.

    That is what netpbm is for.

    You could just do

    CALL EXECUTE_COMMAND_LINE ("pngtopng yourfile.ppm > yourfile.png")

    from your Fortran program, this should work. It might open a
    cmd window, though.

    Is there a pngtopng programme ? Do you mean pnmtopng perhaps ?

    Yes, of course.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to Thomas Koenig on Sun Nov 13 05:39:23 2022
    "Thomas Koenig" wrote in message news:tkqk55$38e2i$1@newsreader4.netcologne.de...

    If you are using threads, you will probably need -frecursive
    to make sure that all variables are on the stack.

    No, I explicitly declare all my procedures as recursive.

    If your thread exited (how did you do that?) it might
    have cleaned up after itself in some way, and left
    the runtime in an inconsistent state.

    I think that's inconsistent with the symptoms in that
    if the calling program is stalled waiting for input the
    data is not lost. Maybe I will put a call Sleep(1000) or
    so as a workaround but I have other stuff I have to mess
    with in the immediate future.

    The least you probably have to do is to make sure that any I/O
    library calls are only executed on a single thread, by putting
    the Windows equivalent of "omp critical" around it.

    In earlier testing this was no problem, just somewhat
    difficult to interpret output. When the failure occurs only
    the failing thread is performing I/O.

    If it's a hobby project, maybe you want to completely rewrite it in gtk-fortran :-)

    There are problems with that project I have mentioned
    long ago, and it's not really a Windows thing. Can you
    create an OpenGK render context in gtk-fortran, for
    example? Linux has this issue with graphics that there
    are different foundations, like X11 is what non-Linux
    speakers would have thought was the foundation in
    Linux, but it's built on top of another package whose
    name I can't recall any more. Everyone on Linux seems
    to use GLUT, which is a bad sign.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Koenig@21:1/5 to James Van Buskirk on Sun Nov 13 14:18:52 2022
    James Van Buskirk <not_valid@comcast.net> schrieb:
    "Thomas Koenig" wrote in message news:tkqk55$38e2i$1@newsreader4.netcologne.de...

    If you are using threads, you will probably need -frecursive
    to make sure that all variables are on the stack.

    No, I explicitly declare all my procedures as recursive.

    If your thread exited (how did you do that?) it might
    have cleaned up after itself in some way, and left
    the runtime in an inconsistent state.

    I think that's inconsistent with the symptoms in that
    if the calling program is stalled waiting for input the
    data is not lost.

    It might still be in an inconsistent state.

    libgfortran is simply not built for several threads
    doing stuff without it knowing about it. It does locking,
    but only for pthreads.

    so as a workaround but I have other stuff I have to mess
    with in the immediate future.

    :-)


    The least you probably have to do is to make sure that any I/O
    library calls are only executed on a single thread, by putting
    the Windows equivalent of "omp critical" around it.

    In earlier testing this was no problem, just somewhat
    difficult to interpret output. When the failure occurs only
    the failing thread is performing I/O.

    Accessing


    If it's a hobby project, maybe you want to completely rewrite it in
    gtk-fortran :-)

    There are problems with that project I have mentioned
    long ago, and it's not really a Windows thing. Can you
    create an OpenGK render context in gtk-fortran, for
    example?

    I assume you mean OpenGL?

    Does https://docs.gtk.org/gtk4/class.GLArea.html qualify?
    (I don't know a lot about OpenGL, so I am just guessing).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Jones@21:1/5 to James Van Buskirk on Sun Nov 13 15:46:34 2022
    James Van Buskirk wrote:

    OK, I made some progress in my hobby project and now it
    displays a graph of its results. I put a READ(*,'(a)') statement
    at the end so my graphs wouldn't go away when the
    program terminates.

    After considerable effort I found out how to write a *.ppm
    file and how to get gimp.exe to convert all of my *.ppm
    files (which most software can't read) to *.png.

    Then I wrote a *.bat file that permits me to run a bunch
    of scenarios. Since I didn't want to have to change focus
    to the CMD.exe window and hit <ENTER> for every run
    of the program, I had it detect when it was running in batch
    mode and skip the READ(*,'(a)') statement because the
    graphs would be available in *.png form anyway.

    However, this caused a problem because the last and of
    course most important *.ppm doesn't complete writing
    before its thread closes, so I don't get that *.ppm file.
    I tried putting a FLUSH(iunit) statement before the
    CLOSE(iunit) statement, but still no joy. How am I
    supposed to tell the thread to wait for the *.ppm file
    to get properly written and saved before returning?

    Have you tried a WAIT or SLEEP function to provide the required delay
    of a small faction of a second, as judged by experience?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From John@21:1/5 to All on Sun Nov 13 07:28:00 2022
    No direct help for the issues you describe that someone has not mentioned already, but if you are just writing Poskanzer pixelmaps from a batch problem I would mention a few other possibilities

    It sounds like you using a lot of MSWIndows-specific components, threaded, and so on. On the other hand you seem to be creating a P6 file at a low level. If you have an internal array representing a pixel map you might consider writing GIF; I have used

    https://fortranwiki.org/fortran/show/writegif

    which is in Fortran and so can be very portable with no dependencies.

    I am a fan of Netpbm+ for batch use, and have generated low-level P6 graphics quite a bit (even have a hopefully portable module just for that); see https://github.com/urbanjost/M_pixel and https://github.com/urbanjost/M_draw for example. That
    approach can work very well for simple projects where longevity and portability matter; particularly with batch-generated graphics (I have programs that have been on dozens of OSes and are decades old still running taking that approach) but it is not
    the way to go for high-level event-driven threaded codes or for most high-level graphics. So not quite sure such a low-level approach is of any use; but thought I would mention it as you are mentioning P6 files (again, have used them for years with
    great success).




    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to seem to incorporate the capability on Sun Nov 13 13:26:32 2022
    "John" wrote in message news:7f7fcb28-c232-468e-9432-04801f51cbf6n@googlegroups.com...

    No direct help for the issues you describe that someone has
    not mentioned already, but if you are just writing Poskanzer
    pixelmaps from a batch problem I would mention a few other
    possibilities

    It sounds like you using a lot of MSWIndows-specific
    components, threaded, and so on. On the other hand you
    seem to be creating a P6 file at a low level. If you have an
    internal array representing a pixel map you might consider
    writing GIF; I have used

    https://fortranwiki.org/fortran/show/writegif

    It's too bad it's writing GIFs rather than PNGs. It doesn't
    seem to incorporate the capability to write animated GIFs
    and GIFs have limitations.

    which is in Fortran and so can be very portable with
    no dependencies.

    I am a fan of Netpbm+ for batch use, and have generated
    low-level P6 graphics quite a bit (even have a hopefully
    portable module just for that); see
    https://github.com/urbanjost/M_pixel and
    https://github.com/urbanjost/M_draw
    for example. That approach can work very well for
    simple projects where longevity and portability matter;
    particularly with batch-generated graphics (I have programs
    that have been on dozens of OSes and are decades old still
    running taking that approach) but it is not the way to go
    for high-level event-driven threaded codes or for most
    high-level graphics. So not quite sure such a low-level
    approach is of any use; but thought I would mention it
    as you are mentioning P6 files (again, have used them for
    years with great success).

    Yeah, P6 *.ppm is the graphics file format for the rest of us:
    you can just look at the specification and generate graphics
    files immediately. It's too bad that more software can't
    read them.

    I see that M_pixel does do animated GIFs. It's a pity that
    there isn't an obvious link on the page that tells you how
    to download the package. I can't understand why GitHub
    doesn't provide that.

    I would just do raw raster graphics if it weren't for the fonts.
    You know, like a Fortran mathjax to raster library :)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gary Scott@21:1/5 to Gary Scott on Sun Nov 13 14:22:37 2022
    On 11/13/2022 2:18 PM, Gary Scott wrote:
    On 11/13/2022 2:46 AM, James Van Buskirk wrote:
    OK, I made some progress in my hobby project and now it
    displays a graph of its results.  I put a READ(*,'(a)') statement
    at the end so my graphs wouldn't go away when the
    program terminates.

    After considerable effort I found out how to write a *.ppm
    file and how to get gimp.exe to convert all of my *.ppm
    files (which most software can't read) to *.png.

    Then I wrote a *.bat file that permits me to run a bunch
    of scenarios.  Since I didn't want to have to change focus
    to the CMD.exe window and hit <ENTER> for every run
    of the program, I had it detect when it was running in batch
    mode and skip the READ(*,'(a)') statement because the
    graphs would be available in *.png form anyway.

    However, this caused a problem because the last and of
    course most important *.ppm doesn't complete writing
    before its thread closes, so I don't get that *.ppm file.
    I tried putting a FLUSH(iunit) statement before the
    CLOSE(iunit) statement, but still no joy.  How am I
    supposed to tell the thread to wait for the *.ppm file
    to get properly written and saved before returning?

    I sometimes use a shared memory buffer to communication with separate processes or threads.  Example of the win32 api for this is here:

    https://www.fortranlib.com/ShareBufferWin32.f90

    You can make it virtually any size you want.  I sometimes use various
    flags (wait, kill, etc.) to synchronize with hardware or software.




    Here's the example at the bottom of the linked file:

    !
    ! Example Main Program 1
    !
    ! integer :: iretcode, bufptr, buffer(1024)
    !
    ! pointer (bufptr,buffer)
    !
    !
    ! call CreateShareBuffer('TestBuf',4096,bufptr,iretcode)
    !
    !
    ! ...code using BUFFER goes here.
    !
    ! ...when finished...
    !
    !
    ! call DeleteShareBuffer(bufptr,iretcode)
    !
    ! end
    !
    !
    !
    ! Example Main Program 2 (3, 4, etc.)
    !
    ! integer :: iretcode, bufptr, buffer(1024)
    !
    ! pointer (bufptr,buffer)
    !
    !
    ! call OpenShareBuffer('TestBuf',bufptr,iretcode)
    !
    !
    ! ...code using BUFFER goes here.
    !
    ! ...when finished...
    !
    !
    ! call CloseShareBuffer(bufptr,iretcode)
    !
    ! end

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gary Scott@21:1/5 to James Van Buskirk on Sun Nov 13 14:18:59 2022
    On 11/13/2022 2:46 AM, James Van Buskirk wrote:
    OK, I made some progress in my hobby project and now it
    displays a graph of its results.  I put a READ(*,'(a)') statement
    at the end so my graphs wouldn't go away when the
    program terminates.

    After considerable effort I found out how to write a *.ppm
    file and how to get gimp.exe to convert all of my *.ppm
    files (which most software can't read) to *.png.

    Then I wrote a *.bat file that permits me to run a bunch
    of scenarios.  Since I didn't want to have to change focus
    to the CMD.exe window and hit <ENTER> for every run
    of the program, I had it detect when it was running in batch
    mode and skip the READ(*,'(a)') statement because the
    graphs would be available in *.png form anyway.

    However, this caused a problem because the last and of
    course most important *.ppm doesn't complete writing
    before its thread closes, so I don't get that *.ppm file.
    I tried putting a FLUSH(iunit) statement before the
    CLOSE(iunit) statement, but still no joy.  How am I
    supposed to tell the thread to wait for the *.ppm file
    to get properly written and saved before returning?

    I sometimes use a shared memory buffer to communication with separate
    processes or threads. Example of the win32 api for this is here:

    https://www.fortranlib.com/ShareBufferWin32.f90

    You can make it virtually any size you want. I sometimes use various
    flags (wait, kill, etc.) to synchronize with hardware or software.


    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to David Jones on Sun Nov 13 13:35:04 2022
    "David Jones" wrote in message news:tkr3gq$nkk$1@gioia.aioe.org...

    James Van Buskirk wrote:
    However, this caused a problem because the last and of
    course most important *.ppm doesn't complete writing
    before its thread closes, so I don't get that *.ppm file.
    I tried putting a FLUSH(iunit) statement before the
    CLOSE(iunit) statement, but still no joy. How am I
    supposed to tell the thread to wait for the *.ppm file
    to get properly written and saved before returning?

    Have you tried a WAIT or SLEEP function to provide the required delay
    of a small faction of a second, as judged by experience?

    Yeah, that's the first thing I plan to try when I get the
    resources (time and energy) to struggle with this problem
    again. It might need to be a couple of seconds, but the
    overall program takes a couple of minutes to run at
    parameters near to what currently makes it crash by
    flying too close to the sun.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to Gary Scott on Sun Nov 13 13:42:10 2022
    "Gary Scott" wrote in message news:tkrjfj$1h7po$1@dont-email.me...

    I sometimes use a shared memory buffer to communication with separate processes or threads. Example of the win32 api for this is here:

    https://www.fortranlib.com/ShareBufferWin32.f90

    You can make it virtually any size you want. I sometimes use various
    flags (wait, kill, etc.) to synchronize with hardware or software.

    I seems that your solution would be to create a shared buffer that
    the dying thread would allocate and fill with data in its last gasp
    and then the main program would write the data to file.

    I think that might work but I was hoping for a solution that
    preserved the current division of labor.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Jones@21:1/5 to James Van Buskirk on Sun Nov 13 22:45:04 2022
    James Van Buskirk wrote:

    "David Jones" wrote in message news:tkr3gq$nkk$1@gioia.aioe.org...
    James Van Buskirk wrote:
    However, this caused a problem because the last and of
    course most important *.ppm doesn't complete writing
    before its thread closes, so I don't get that *.ppm file.
    I tried putting a FLUSH(iunit) statement before the
    CLOSE(iunit) statement, but still no joy. How am I
    supposed to tell the thread to wait for the *.ppm file
    to get properly written and saved before returning?

    Have you tried a WAIT or SLEEP function to provide the required
    delay of a small faction of a second, as judged by experience?

    Yeah, that's the first thing I plan to try when I get the
    resources (time and energy) to struggle with this problem
    again. It might need to be a couple of seconds, but the
    overall program takes a couple of minutes to run at
    parameters near to what currently makes it crash by
    flying too close to the sun.

    A possible (flexible on time?) strategy might be to interactively try
    to open-for-exclusive-read the file once you have closed it, with a
    WAIT or SLEEP between tries. THIs mighrt ensure the system thinks the
    file properly exists before you close the program.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gary Scott@21:1/5 to James Van Buskirk on Sun Nov 13 18:12:32 2022
    On 11/13/2022 2:42 PM, James Van Buskirk wrote:
    "Gary Scott"  wrote in message news:tkrjfj$1h7po$1@dont-email.me...
    I sometimes use a shared memory buffer to communication with separate
    processes or threads.  Example of the win32 api for this is here:

    https://www.fortranlib.com/ShareBufferWin32.f90

    You can make it virtually any size you want.  I sometimes use various
    flags (wait, kill, etc.) to synchronize with hardware or software.

    I seems that your solution would be to create a shared buffer that
    the dying thread would allocate and fill with data in its last gasp
    and then the main program would write the data to file.

    I think that might work but I was hoping for a solution that
    preserved the current division of labor.

    I don't think the division of labor would need to change, just use one
    or two shared variables (in the swap file) to communicate between the
    threads and synchronize as needed. Maybe when the thread is done, it
    sets a shared flag when it completes or it waits until the main sets a
    flag to allow the thread to continue/process. Better than an arbitrary wait/delay.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to James Van Buskirk on Sun Nov 13 15:47:36 2022
    On Sunday, November 13, 2022 at 2:04:12 AM UTC-8, James Van Buskirk wrote:

    (snip)

    No, Windows threads with _beginthreadex() and the
    whole 9 yards. I tried putting a WaitForSingleObject
    call before program termination, but it had no effect.
    Seemingly the thread (and my *.ppm file) were already
    long gone by that time.

    Sounds like a Windows bug.

    Any asynchronous operation should have the ability to WAIT for
    it to finish.

    Fortran asynchronous I/O has a WAIT statement such that you can
    wait for the operation to be done. For READ, you can't look at the data
    until after the WAIT. For WRITE, you can't reuse the output buffer until
    after WAIT.

    For OS/360, I/O is naturally asynchronous, each operation has an ECB
    (Event Control Block) which is used with a WAIT macro. And as above,
    you can't use the read data, or reuse the output buffer, until the WAIT
    has finished.

    So, for example, you do double buffer I/O by starting two READ operations,
    and then WAITing for the first. When it is done, you use the data supplied. (Or copy it away somewhere.) Then start the third and WAIT for the second.

    And subtasks also have an ECB and you can WAIT for them.

    IBM versions of PL/I have EVENT variables, which most likely have
    the ECB inside them, and a WAIT statement. That is used for both
    asynchronous I/O and subtasks.

    Asynchronous operations are pretty fundamental in Unix, too.

    It might be, though, that they were added on later to Windows, and not
    so well integrated as they could have been.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gary Scott@21:1/5 to Gary Scott on Sun Nov 13 20:10:18 2022
    On 11/13/2022 7:59 PM, Gary Scott wrote:
    On 11/13/2022 6:12 PM, Gary Scott wrote:
    On 11/13/2022 2:42 PM, James Van Buskirk wrote:
    "Gary Scott"  wrote in message news:tkrjfj$1h7po$1@dont-email.me...
    I sometimes use a shared memory buffer to communication with
    separate processes or threads.  Example of the win32 api for this is
    here:

    https://www.fortranlib.com/ShareBufferWin32.f90

    You can make it virtually any size you want.  I sometimes use
    various flags (wait, kill, etc.) to synchronize with hardware or
    software.

    I seems that your solution would be to create a shared buffer that
    the dying thread would allocate and fill with data in its last gasp
    and then the main program would write the data to file.

    I think that might work but I was hoping for a solution that
    preserved the current division of labor.

    I don't think the division of labor would need to change, just use one
    or two shared variables (in the swap file) to communicate between the
    threads and synchronize as needed.  Maybe when the thread is done, it
    sets a shared flag when it completes or it waits until the main sets a
    flag to allow the thread to continue/process.  Better than an
    arbitrary wait/delay.
    Another possibility that I sometimes use is shared file access.  On
    windows, I'll reserve usually a header at the beginning of the file
    (usually direct access, but it works with stream and other forms as
    well).  The header may contain a flag to indicate the availability state
    for reading or writing by other processes (or threads).  In my
    application, I also implemented record locks in each record (and
    timestamps at beginning and end of record and check sums, etc.).  It
    seems completely reliable.  I've never had a data corruption in decades
    and billions of read/writes, knock on wood :)

    SHARE
    'DENYRW'
    'DENYWR'
    'DENYRD'
    'DENYNONE'
    File locking
    'DENYWR'
    Note: The default differs under certain conditions (see SHARE Specifier). Other notes:
    'DENYWR': on Linux* and macOS systems, the default depends only on the
    FORM setting.
    'DENYRD': applies to Windows.
    SHARED
    No value
    File sharing allowed
    Linux* and macOS: SHARED
    Windows: Not shared
    Of course you have to be careful with some forms as they will truncate
    the file if you try to write to a "header". You'll have to open the
    file with a form that allows you to "tweak" the contents in place.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gary Scott@21:1/5 to Gary Scott on Sun Nov 13 19:59:01 2022
    On 11/13/2022 6:12 PM, Gary Scott wrote:
    On 11/13/2022 2:42 PM, James Van Buskirk wrote:
    "Gary Scott"  wrote in message news:tkrjfj$1h7po$1@dont-email.me...
    I sometimes use a shared memory buffer to communication with separate
    processes or threads.  Example of the win32 api for this is here:

    https://www.fortranlib.com/ShareBufferWin32.f90

    You can make it virtually any size you want.  I sometimes use various
    flags (wait, kill, etc.) to synchronize with hardware or software.

    I seems that your solution would be to create a shared buffer that
    the dying thread would allocate and fill with data in its last gasp
    and then the main program would write the data to file.

    I think that might work but I was hoping for a solution that
    preserved the current division of labor.

    I don't think the division of labor would need to change, just use one
    or two shared variables (in the swap file) to communicate between the
    threads and synchronize as needed.  Maybe when the thread is done, it
    sets a shared flag when it completes or it waits until the main sets a
    flag to allow the thread to continue/process.  Better than an arbitrary wait/delay.
    Another possibility that I sometimes use is shared file access. On
    windows, I'll reserve usually a header at the beginning of the file
    (usually direct access, but it works with stream and other forms as
    well). The header may contain a flag to indicate the availability state
    for reading or writing by other processes (or threads). In my
    application, I also implemented record locks in each record (and
    timestamps at beginning and end of record and check sums, etc.). It
    seems completely reliable. I've never had a data corruption in decades
    and billions of read/writes, knock on wood :)

    SHARE
    'DENYRW'
    'DENYWR'
    'DENYRD'
    'DENYNONE'
    File locking
    'DENYWR'
    Note: The default differs under certain conditions (see SHARE Specifier).
    Other notes:
    'DENYWR': on Linux* and macOS systems, the default depends only on the
    FORM setting.
    'DENYRD': applies to Windows.
    SHARED
    No value
    File sharing allowed
    Linux* and macOS: SHARED
    Windows: Not shared

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to All on Sun Nov 13 19:46:55 2022
    "gah4" wrote in message news:10f6e9a0-658b-41db-b500-cf1474588555n@googlegroups.com...

    Fortran asynchronous I/O has a WAIT statement such that you can
    wait for the operation to be done. For READ, you can't look at the data until after the WAIT. For WRITE, you can't reuse the output buffer until after WAIT.

    I didn't realize that the committee had sneaked asynchronous I/O in
    there. Unfortunately, as Thomas Koenig said, it doesn't work in
    gfortran on Windows.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to David Jones on Sun Nov 13 20:03:45 2022
    "David Jones" wrote in message news:tkrs1g$1q1t$1@gioia.aioe.org...

    A possible (flexible on time?) strategy might be to interactively try
    to open-for-exclusive-read the file once you have closed it, with a
    WAIT or SLEEP between tries. THIs mighrt ensure the system thinks the
    file properly exists before you close the program.

    call Sleep(1000)

    seemed to work consistently and I don't want to spend too much
    time on this problem. What happens if you can open for exclusive
    read and then the writing process decides that now is the time to
    open the file for writing?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From gah4@21:1/5 to James Van Buskirk on Sun Nov 13 21:40:27 2022
    On Sunday, November 13, 2022 at 7:04:47 PM UTC-8, James Van Buskirk wrote:

    (snip)

    seemed to work consistently and I don't want to spend too much
    time on this problem. What happens if you can open for exclusive
    read and then the writing process decides that now is the time to
    open the file for writing?

    One of the fun things about Unix is that it mostly doesn't even try to
    do file locking. Programs can do any (more than one) thing to a file
    at the same time, sometimes with strange results.

    Windows tries to do file locking, more often than not, locking you
    out from something you should be able to do.

    The computer that I write this on is a MacBook Air with some disks
    NFS mounted off servers on the network. I had to put nolocks on
    the NFS mount command, otherwise it keeps locking them when
    it isn't supposed to.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Koenig@21:1/5 to James Van Buskirk on Mon Nov 14 06:40:24 2022
    James Van Buskirk <not_valid@comcast.net> schrieb:
    "gah4" wrote in message news:10f6e9a0-658b-41db-b500-cf1474588555n@googlegroups.com...

    Fortran asynchronous I/O has a WAIT statement such that you can
    wait for the operation to be done. For READ, you can't look at the data
    until after the WAIT. For WRITE, you can't reuse the output buffer until
    after WAIT.

    I didn't realize that the committee had sneaked asynchronous I/O in
    there. Unfortunately, as Thomas Koenig said, it doesn't work in
    gfortran on Windows.

    The committee left in a loophole so that it was OK for asynchronous
    I/O to be done synchronously, which how gfortran implemented it
    until 2018.

    The implementation is built on pthreads, though.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From John@21:1/5 to James Van Buskirk on Mon Nov 14 06:43:27 2022
    On Sunday, November 13, 2022 at 3:36:07 PM UTC-5, James Van Buskirk wrote:
    "David Jones" wrote in message news:tkr3gq$nkk$1...@gioia.aioe.org...
    James Van Buskirk wrote:
    However, this caused a problem because the last and of
    course most important *.ppm doesn't complete writing
    before its thread closes, so I don't get that *.ppm file.
    I tried putting a FLUSH(iunit) statement before the
    CLOSE(iunit) statement, but still no joy. How am I
    supposed to tell the thread to wait for the *.ppm file
    to get properly written and saved before returning?

    Have you tried a WAIT or SLEEP function to provide the required delay
    of a small faction of a second, as judged by experience?
    Yeah, that's the first thing I plan to try when I get the
    resources (time and energy) to struggle with this problem
    again. It might need to be a couple of seconds, but the
    overall program takes a couple of minutes to run at
    parameters near to what currently makes it crash by
    flying too close to the sun.
    RE: Tips on downloading a github package ...

    When you are looking at github packages, you can use a git command (or git GUI) and copy an entire repo to your platform, as in

    git clone https://github.com/urbanjost/M_draw.git

    or if you are an fpm(1) user you can just list the repository as a dependency; if the maintainer made
    a release file that should be a single file in zip or tar format that contains the entire repository;

    but if not a git user and there is no release files for specific versions, a regular download is (oddly)
    under the [CODE] button on the right (not the [CODE] button on the upper left). It gives you an option
    there to download the project as a ZIP file that is built on the file.

    RE: fonts

    Yeah, currently M_pixel just has a couple of built-in Hershey vector fonts; M_draw has a much better Hershey font support and very basic hardware font support on devices that have them; for my uses that works very well as it is highly portable; but
    not very attractive.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Koenig@21:1/5 to James Van Buskirk on Mon Nov 14 17:55:10 2022
    James Van Buskirk <not_valid@comcast.net> schrieb:
    "David Jones" wrote in message news:tkr3gq$nkk$1@gioia.aioe.org...

    James Van Buskirk wrote:
    However, this caused a problem because the last and of
    course most important *.ppm doesn't complete writing
    before its thread closes, so I don't get that *.ppm file.
    I tried putting a FLUSH(iunit) statement before the
    CLOSE(iunit) statement, but still no joy. How am I
    supposed to tell the thread to wait for the *.ppm file
    to get properly written and saved before returning?

    Have you tried a WAIT or SLEEP function to provide the required delay
    of a small faction of a second, as judged by experience?

    Yeah, that's the first thing I plan to try when I get the
    resources (time and energy) to struggle with this problem
    again.

    Another possibility: Have the writing thread open the file under
    another name, and upon completion, rename it to the final name
    (using the non-standard RENAME function or subroutine).

    The other thread can then INQUIRE for the existence of
    the file in a loop, possibly with a SLEEP thrown in.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Van Buskirk@21:1/5 to All on Mon Nov 14 19:01:50 2022
    "Thomas Koenig" wrote in message news:tktvdu$3amf6$1@newsreader4.netcologne.de...

    James Van Buskirk <not_valid@comcast.net> schrieb:
    "David Jones" wrote in message news:tkr3gq$nkk$1@gioia.aioe.org...

    James Van Buskirk wrote:
    However, this caused a problem because the last and of
    course most important *.ppm doesn't complete writing
    before its thread closes, so I don't get that *.ppm file.
    I tried putting a FLUSH(iunit) statement before the
    CLOSE(iunit) statement, but still no joy. How am I
    supposed to tell the thread to wait for the *.ppm file
    to get properly written and saved before returning?

    Have you tried a WAIT or SLEEP function to provide the required delay
    of a small faction of a second, as judged by experience?

    Yeah, that's the first thing I plan to try when I get the
    resources (time and energy) to struggle with this problem
    again.

    Another possibility: Have the writing thread open the file under
    another name, and upon completion, rename it to the final name
    (using the non-standard RENAME function or subroutine).

    The other thread can then INQUIRE for the existence of
    the file in a loop, possibly with a SLEEP thrown in.

    Given that the 'right' solution is asynchronous I/O and that
    I have a workaround with Sleep, I have put this issue on the
    backburner for now.

    At this point the graphics isn't too bad if you consider the
    lack of Greek characters and subscripts in the axis labels
    and title, so I am back to the calculational component.
    I am trying to determine whether I need arbitrary
    precision and how much good it will do me. The present
    limit seems to be due to an ill-conditioned Jacobian in a
    context where another approach may be able to make
    forward progress.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)