TL;DR: …what @everythingfunctional said.
unportable internals exposed below
Inspecting the symbols using nm
from binutils, it wasn’t hard to find a routine responsible for launching multiple images:
// WARNING: may be incorrect!
int for_rtl_ICAF_LAUNCH(int /*num_images*/, char* /*config*/, void * /* ??? */);
The first argument is the number of images corresponding to the flag -coarray-num-images=
(no flag results in -1, giving as many images as available cores). The second argument corresponds to the argument of the flag -coarray-config-file=
. I don’t know what the third argument is for; values other than NULL would crash the entire process .
If you compile a coarray program with ifx in compiler explorer, another procedure appears:
caflaunch$MAIN$blk:
push rax
mov edi, -1
xor esi, esi
xor edx, edx
call for_rtl_ICAF_LAUNCH@PLT
test al, 1
jne .LBB1_1
mov edi, offset __unnamed_3
pop rax
jmp for_exit@PLT
.LBB1_1:
pop rax
ret
which can be roughly decompiled to:
// "fake" caflaunch$MAIN$blk
extern "C" int caflaunch(void) {
int result = for_rtl_ICAF_LAUNCH(-1,nullptr,nullptr);
if ((result & 1) != 0) {
return result;
}
return for_exit(0);
}
What is weird is that I couldn’t find any reference to this procedure (or it’s address) in the object file, so it remains unclear when or how this procedure is invoked and why it is there in the first place.
Empirically, calling the routine seems to fork the process and create multiple images:
int main(int argc, char **argv) {
for_rtl_init_(&argc, argv);
caflaunch();
// vvv multiple images running vvv
some_caf_subroutine();
for_rtl_finish_(); // ignore status
return 0;
}
No matter what I tried, I couldn’t find a way to join the images back together and this behavior essentially matches the MPI model (upon which the Intel Coarray Fortran implementation is based). After a call to MPI_Finalize
the number of processes (images) remains undefined, and the expectation is the program will exit.
So my suggestion for anyone trying to incorporate a coarray section into a non-Fortran program, would be to either:
- launch a separate process and read/write whatever values needed using an external file
- launch a separate process and communicate using IPC (this could be as simple as reading and writing to stdin/stdout)
- invoke the non-Fortran program from the coarray Fortran program as suggested in the other thread