Use coarrays with a C main program

TL;DR: …what @everythingfunctional said.

:warning: unportable internals exposed below :warning:

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 :bomb:.

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