<div class="gmail_quote">On Fri, Jun 1, 2012 at 3:38 PM, Blaise Bourdin <span dir="ltr"><<a href="mailto:bourdin@lsu.edu" target="_blank">bourdin@lsu.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="im"><blockquote type="cite"><div class="gmail_quote"><div>Having the interfaces requires those extra interface files in the includes that we already hate so much, and we can't protect the headers (to make including the right ones simple like in C) because you have to include them for every subroutine.</div>
</div></blockquote><div><br></div></div>Not really. You don't need to include the modules in each subroutine or function if they are included (used) in the Program or Module in which the function is defined</div></blockquote>
<div><br></div><div>I was referring to #include *.h90 files.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="im"><div></div></div><div>
Apart for [1], I fully agree. I actually think that there should only be two way to use fortran: the old f77 way without any type checking, interface, and where all petscobjects are integer, or the right way which you described.</div>
</div></blockquote><div><br></div><div>What about people with legacy code that want to use VecGetArrayF90? Should they have to rewrite with type(Mat) everywhere just for that change? What about mixing two Fortran codes, one of which does things the new way and one does the old way?</div>
<div> </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="im"><blockquote type="cite"><div class="gmail_quote"><div>Unfortunately, that forces people to spell out things like type(Mat) [2] and XGetContext() either requires an explicit interface written by the user [3] or use of the ISO C bindings in the interface [4].</div>
</div></blockquote></div><div>Not really. As long as your context is not too large (so that allocating a copy and copying the data won't kill you), you can always write a generic interface for XGetContext that returns an array of your favorite data type, then use transfer. And when your context is large, you should pass by address anyway). Conceptually, it is not really different from casting into a *void. McCormick has a nice writeup on this <a href="http://www.macresearch.org/advanced_fortran_90_callbacks_with_the_transfer_function" target="_blank">http://www.macresearch.org/advanced_fortran_90_callbacks_with_the_transfer_function</a></div>
<div><br></div><div>How does using iso_c_binding helps with a fortran library called from fortran? </div></div></blockquote><div><br></div><div>I had a 50 message conversation about this with Ondrej Certik this winter. He eventually agreed with me and summarized the various choices here.</div>
<div><br></div><div><a href="http://fortran90.org/src/best-practices.html#type-casting-in-callbacks">http://fortran90.org/src/best-practices.html#type-casting-in-callbacks</a></div><div><br></div><div>Choice 5 (V) is the preferred way to do this. With transfer (choice 6), you have to write 30 lines of boilerplate to define typeX2data and data2typeX for each typeX that you want to be able to pass through a callback (but at least you don't have to write an interface to every function you pass the context through). Transfer is also a very different (and worse) semantic because you get a copy of the actual data structure, thus any modifications that you make from the callback (e.g. logging some statistics) will not be visible in the external context.</div>
<div><br></div><div>Compare the gists (cited at the bottom of that page)</div><div><br></div><div><a href="https://gist.github.com/1665626">https://gist.github.com/1665626</a> (best way I know, uses ISO C bindings)</div><div>
<a href="https://gist.github.com/1665630">https://gist.github.com/1665630</a> (note the need for my_data_type.f90)</div><div><br></div><div>I'm relieved that ISO C bindings exist, at least it's possible to write modular software now, but you know the standards committee was impaired or sadistic when the foreign function interface is better than the native function interface. </div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="im"><div></div><blockquote type="cite"><div class="gmail_quote">
<div>I can think of no explanation for this absurdity other than that the Fortran language standards committee is the most successful global trolling agency in modern history [5].</div></div></blockquote></div></div></blockquote>
<div>Not even an emoticon? I thought this was funny. </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="im"><blockquote type="cite"><div>[1] Better, but it would be best for them to stop using Fortran.</div>
</blockquote></div><div>Why not. But what is the alternative knowing that I am not willing to give up array sections, operator overloading and vector operations? Are you going to suggest that I switch to C++? </div></div>
</blockquote><div><br></div><div>You are aware that every use of non-leading dimension stride 1 array sections involves a dynamic memory allocation, a copy in, and a copy out?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="im"><blockquote type="cite"><div>[2] No #includes means no macros [6] and no equivalent of typedef.</div></blockquote></div>The only macro I would miss are CHKERRQ and SETERRQ. I would actually make an exception for these two. For numerical and string types, the fortran way of doing typedef is kind.</div>
</blockquote><div><br></div><div>The kind parameter still pollutes the namespace (don't get me started on how bad they botched namespaces ;-)) and has to appear throughout the code and can't be used for types like Vec, Mat, etc. Fortran could claim to have a useful typedef when I can do the equivalent of</div>
<div><br></div><div>typedef struct _p_KSP *KSP;</div><div>typedef PetscErrorCode (*TSIFunction)(TS,PetscReal,Vec,Vec,Vec,void*); </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="im"><blockquote type="cite"><div>[3] Disaster because (a) it is maintained by the user with no way to check that it is correct and (b) the user may need multiple incompatible definitions in the same project.</div>
<div>[4] Indeed, the best way to write a Fortran library called from Fortran is to use the ISO C bindings.</div><div>[5] The people who dream up ways to link MKL and the Portland Group deserve honorable mention.</div><div>
[6] Type macros are terrible anyway because of the aforementioned punchcard nostalgia leading to different projects adopting different line/format styles and compilers having no portable way to select.</div></blockquote>
</div>I don't know of any compiler which does not default to free form for .f90/.F90 files, do you? Free format has been around for over 20 years. That some people insist on coding on 72 cols (or is it 78?) in the days of large screens is beyond me indeed. </div>
</blockquote><div><br></div><div>As a library, we should be able to make the library part work the same regardless of which choice the *user* makes. This is especially important when coupling two codes written by users with different conventions. You will notice in PETSc Fortran files that we place the line continuation character (&) in column 73 so that it is ignored by a fixed form compiler (because it's not between columns 7 to 72) as well as a continuation character in column 6 so that fixed form compilers know it's a continuation. We also avoid using line continuations at all in rows that have macros because the macro may expand to different length strings.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div></div><div>So I guess that you guys don't want an explicit interface for PetscBagRegisterEnum, right? I'll fix the harmless bugs in the current binding, then.</div>
</blockquote></div><br><div>It should be there just like VecGetArrayF90 needs one, I just felt like ranting. ;-D</div>