My Modern Fortran book is now published

You can’t have unit = * in an inquire statement: how would the system know whether you wanted input_unit or output_unit?

Without some other flag or option I cannot think of a way, but I thought someone told me you could when he was asking why I virtually never use asterisk (any more; I used to). So I guess that is still a valid reason to prefer using unit number labels. Oddities between compilers and/or operating systems on whether * and 5 and 6 referred to the same connection or not, whether closing or rewinding affected the *-associated file, and so on caused enough issues with portability that once the ISO_FORTRAN_ENV implementation because common enough I essentially quit using asterisks; so I have not even paid attention to whether some of those questions/differences have been standardized or not. Getting off-topic from the book, but if the book is updated, the problems with asterisk and INQUIRE/REWIND/OPEN and padding and delimiters and such is worth mentioning, perhaps.

I noticed this thread a bit late, but better late than never…
Congratulations @milancurcic for your book, and best wishes for its journey in the market! I am pretty sure I will find useful information in it - especially in parts 3 and 4, but probably earlier as well. I ordered my printed copy - since I really hate reading long texts from a computer screen - after all, nothing can replace a real book.

Besides that, I am glad another book about Modern Fortran is published in an era when - against any common sense - programming languages obviously, clearly, blatantly inadequate for scientific computing become more and more commonly used for that task.

5 Likes

Thanks a lot @Pap for your support.The book targets newcomers to Fortran, but I hope you find useful (or at least entertaining) bits here and there.:slightly_smiling_face:

I disagree :wink: I think it’s also for “oldcomers” not familiar with some or all of the new features of Fortran 2003/2008/2018: OOP, coarrays and coroutines, C interoperability, etc. Therefore, if you learned Fortran in the 20th century, it’s a good read to quickly catch up modern Fortran.

Sincerely, at the moment my two principal Fortran books are Modern Fortran: Building Efficient Parallel Applications and Modern Fortran Explained: Incorporating Fortran 2018. Very different styles and objectives, but very complementary, at least for me.

5 Likes

A brief survey about Milan’s book on worldcat.org mentions 173 participating institutions with an edition in print .or. as e-video (128 entries) .or. electronic book (15 entries, survey by 2022-May-01). There is an overlap with institutions offering more than one version, and of course there are libraries to offer access to the book within a package of the online shelves by O’Reilly, Safari Online Books, etc.

Milan @milancurcic,
page 351 of your book, there is that line (middle of the page):

call event_query(time_step_event, time_step_count)

with that comment in the right margin “Blocks until the event is posted”.

I think it is a CTRL+C/CTRL+V error coming from the code at the bottom of page 350 (with event_wait()), as call event_query() is non-blocking but just returns in time_step_count the number of posted events.

Am I right? Page 339 you say it is non-blocking.

1 Like

Thanks, @vmagnin, good catch, you’re correct. event_query doesn’t block. You’re also correct about how this error might have happened. :slight_smile:

I will add to the errata.

1 Like

Another question is:
is it possible to post an event to all images simultaneously? Or only to one image?
Page 341, I don’t know if that is what you are speaking about.

I had to look into this. From my reading of MFE and the working draft of the standard, no.

If coindices to the event variable in event post are omitted, you’re posting to the local copy, that is, the event variable on this image. Otherwise, the co-index must be scalar. I don’t know if there’s a reason that it was designed like this, or merely an oversight.

I imagine it’d be straightforward to write a subroutine to post to all images at once.

Thanks.

Yes, that is strange. I thought omitting the codindices would send to all images… But no (and it is logical). My need is just to stop all images when the image 1 (managing a GTK window) is closed.

I tried this (executed only in image 1):

    if (num_images() >= 2) then
      do i = 2, num_images()
        event post(stop_notification[i])
      end do
    end if

and all images are regularly doing:

call event_query(stop_notification, counter)
print *, counter

But the counter is non zero only in the image 4 (over 4). The images 2 and 3 receive nothing (or am I doing something wrong?).

I am using GFortran 11.2.0 + OpenCoarrays 2.10.0 under Ubuntu 22.04.
I have also tried to use image_status(1) but it does not seem to be implemented yet in OpenCoarrays.

I have now tried with ifort and it’s worse: no image received any event.

I have also tried to add a sync all before or after the event post. No success.

@vmagnin Can you post the complete program? I could look at it and try it on my end.

1 Like

Thanks @milancurcic , I will push it tomorrow (22:37 here!). And open a new post.

1 Like

Dear Milan @milancurcic,

I have found a typo page 246 of your book (listing 9.2 A function to average an array of integers). The comment on the right of that line:

integer, intent(in) :: x(:)

states “Assumed size, one dimensional real array” instead of integer.

(Obviously due to a CTRL+C/CTRL+V of the listing 9.1 on the previous page).


And my naive question is: do generic procedures also work with intent(inout) ot intent(out) arguments?
I would like to have three procedures returning several integers which could be int8, int16 or int32.

1 Like

You could create an interface with module procedures, for example

module m
use iso_fortran_env, only: int32, int64
implicit none
interface twice
   module procedure twice_int32, twice_int64
end interface twice
contains
subroutine twice_int32(i)
integer(kind=int32), intent(in out)  :: i
i = 2*i
end subroutine twice_int32
!
subroutine twice_int64(i)
integer(kind=int64), intent(in out)  :: i
i = 2*i
end subroutine twice_int64
end module m

What you can’t do is pass the kind as a separate argument, as some intrinsic procedures, such as real, allow.

1 Like

Thank you! You can use any intent but you can’t use intent alone to distinguish between specific procedures; it needs to be a distinguishable type, kind, or rank.

1 Like

Also worth noting that that is an assumed shape, not assumed size array.

2 Likes

Indeed, “assumed-shape” like in listings 5.18 and 3.11.

The difference is explained page 307:

This is a somewhat obscure feature of Fortran called assumed-size arrays (in contrast to assumed shape) and applies to array or character string arguments to C functions. It’s there for easier interfacing with C functions, but otherwise you shouldn’t ever use it in pure Fortran programs.

You missed my favorite part from this–the quote from Walter Brainerd. :slight_smile:

2 Likes

It’s there for easier interfacing with C functions, but otherwise you shouldn’t ever use it in pure Fortran programs. To quote the late Walter Brainerd in his book Guide to Fortran 2008 Programming: “Do not ask why—just do it.”

:wink:

And this is your example of an assumed-size array (which uses a star instead of a colon for assumed-shape):

character(c_char), intent(out) :: buf(*)

(does the difference could be somehow related to the fact that C arrays start at 0?)

1 Like