Pass an R package on CRAN with issues on MACOS due + OpenMP
Asked Answered
P

2

8

I have an R package with Fortran and OpenMP than can't pass CRAN. I receive the following message:

Your package no longer installs on macOS with OpenMP issues.

My Makevars file is:

USE_FC_TO_LINK =
PKG_FFLAGS = $(SHLIB_OPENMP_FFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_FFLAGS)

C_OBJS = init.o
FT_OBJS = e_bottomup.o e_topdown.o check_nt.o

all:
    @$(MAKE) $(SHLIB)
    @rm -f  *.o

$(SHLIB): $(FT_OBJS) $(C_OBJS)

init.o:  e_bottomup.o e_topdown.o check_nt.o

How to solve this issue? Thanks.

Edit 1:

I tried adding the flag cpp:

USE_FC_TO_LINK =
PKG_FFLAGS = $(SHLIB_OPENMP_FFLAGS) *-cpp*
PKG_LIBS = $(SHLIB_OPENMP_FFLAGS)

to add the condition #ifdef _OPENMP on Fortran code before !omp...

But with R CMD Check I got the message:

Non-portable flags in variable 'PKG_FFLAGS': -cpp
Peavey answered 3/10, 2020 at 14:30 Comment(4)
You have to protect omp functions with #if undef _OPENMP directivesMaribeth
This is unrelated but the rule init.o: e_bottomup.o e_topdown.o check_nt.o doesn’t make sense. An object file can’t have dependencies on other object files.Clubfoot
Thank for mentioning. I already have no much experience with C and I used based on a template and reading the manualPeavey
@Maribeth I tried in Fortran adding the flag cpp but it did not work. I do not know why there are MACROS to use Fortran with OpenMP on R which dont work on MACOS. Maybe they are designed to develop R packages not on CRAN and for other OS than MACOSPeavey
P
3

The Makevars file is fine. The OMP directives must be commented !$, including the USE OMP.

For instance, I created an R package with Fortran and OMP to test (and play with it).

I included an R function to return the max number of threads in each machine:

get_threads

The Fortran code is :

SUBROUTINE checkntf (nt) 
!$ USE OMP_LIB

IMPLICIT NONE
INTEGER nt

!$ nt = OMP_GET_MAX_THREADS()

RETURN
END

The already install on Windows, Ubuntu and macOS as shown here

enter image description here

Peavey answered 4/12, 2020 at 19:23 Comment(0)
S
2

You can look how the data.table package deal with that using #ifdef _OPENMP: https://github.com/Rdatatable/data.table/blob/master/src/myomp.h It should be pretty similar in Fortran I guess

#ifdef _OPENMP
  #include <omp.h>
#else
  // for machines with compilers void of openmp support
  #define omp_get_num_threads()  1
  #define omp_get_thread_num()   0
  #define omp_get_max_threads()  1
  #define omp_get_thread_limit() 1
  #define omp_get_num_procs()    1
  #define omp_set_nested(a)   // empty statement to remove the call
  #define omp_get_wtime()        0
#endif
Sanjak answered 4/10, 2020 at 23:29 Comment(3)
It did not work. The problem is that #ifdef _OPENMP are illegal on CRAN. For instance, I included #ifdef _OPENMP begore the OPENMP comments but I needed to add the flag cpp here: PKG_FFLAGS = $(SHLIB_OPENMP_FFLAGS) + cpp. But when I check the package it says that it is not allowed.Peavey
I'm doing it, data.table is doing it so it is not illegal. You can open a new question with more details on your actual implementation. Be careful, my answer was for C++. Maybe fortran require some tuning. I know nothing about fortran.Sanjak
You are right. I meant that adding +cpp flag on Fortran it is not allowed. Maybe, adding PKG_CXXFLAGS = $(SHLIB_OPENMP_CXXFLAGS) in addition to PKG_FFLAGS = $(SHLIB_OPENMP_FFLAGS) ?Peavey

© 2022 - 2024 — McMap. All rights reserved.