Error Compiling NCO 4.5.5 with PGI 16.1

All,

I’ve found an issue in trying to build NCO 4.5.5 with PGI 16.1 (as part of the GMAO Baselibs package). It gets to ncwa.c and:

(353) $ mpicc -DHAVE_CONFIG_H -I. -I../.. -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include -DpgiFortran -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/ -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/zlib -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/szlib -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/jpeg -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/hdf5 -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/hdf -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/uuid -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/netcdf -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/udunits2 -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/netcdf -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux//include -DpgiFortran -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/ -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/zlib -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/szlib -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/jpeg -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/hdf5 -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/hdf -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/uuid -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/netcdf -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/udunits2 -I/ford1/share/gmao_SIteam/Baselibs/Internal-5_0_0/x86_64-unknown-linux-gnu/pgfortran_16.1-openmpi_1.10.2/Linux/include/netcdf -fPIC -mp -c -o ncwa.o ncwa.c
PGC-S-0155-rcd must appear in a SHARED or PRIVATE clause (ncwa.c: 1191)
PGC/x86-64 Linux 16.1-0: compilation completed with severe errors

Now, if you look at the code in question, rcd is in a PRIVATE clause…of a sort (shown here broken up a bit):

 859 #pragma omp parallel for default(none) 
   firstprivate(DO_CONFORM_MSK,DO_CONFORM_WGT,ddra_info,rcd) 
   lastprivate(rcd) private(idx,in_id,wgt_avg) shared(MULTIPLY_BY_TALLY,MUST_CONFORM,NRM_BY_DNM,WGT_MSK_CRD_VAR,dmn_avg,dmn_avg_nbr,flg_ddra,flg_rdd,gpe,in_id_arr,msk_nm,msk_val,nbr_var_prc,nco_dbg_lvl,nco_op_t     yp,nco_prg_nm,op_typ_rlt,out_id,trv_tbl,var_prc,var_prc_out,wgt_nm)

As you see it is labeled firstprivate and lastprivate.

I’ve also informed the NCO developers as well as I’m not sure if this is an NCO issue or a PGI issue.

Matt

Hi Matt,

I download loaded NCO and was able to recreate the error. What it looks like to me is that since “default(none)” is only available on a “parallel” construct and “lastprivate” only available on a “for”, when they are combined into a compound directive, we aren’t extending the semantics. In other words, we’re treating a variable in a lastprivate clause as if were needing to be added to a shared or private clause since that’s how the semantics would work if you had “parallel default(none)” and “for” as separate constructs.

I added TPR#22312 and sent it to engineer for further investigation.

I think the simplest work around would be to remove the “default(none)”.

Thanks!
Mat

Here’s a simple reproducing example:

% cat test_last.c
#include <stdio.h>
#include <stdlib.h>

int main() {
int ii,i;
ii=0;
#ifdef OPT1
#pragma omp parallel default(none) shared(ii)
{
#pragma omp for firstprivate(ii) lastprivate(ii)
#elif OPT2
#pragma omp parallel for default(none) firstprivate(ii)
#elif OPT3
// PGI Accepts this but Intel/GCC/IBM complains that ii can't be in more that one data clause
#pragma omp parallel for default(none) shared(ii) firstprivate(ii) lastprivate(ii)
#else
// Intel/GCC/IBM accepts this but PGI complains that ii needs to be in SHARED or PRIVATE
#pragma omp parallel for default(none) firstprivate(ii) lastprivate(ii)
#endif
for(i=0;i< 16; ++i)
{
ii=ii+1;
}
#ifdef OPT1
}
#endif
printf("ii=%d  \n", ii);

exit(0);
}

% gcc -fopenmp test_last.c -DOPT1
% gcc -fopenmp test_last.c -DOPT2
% gcc -fopenmp test_last.c -DOPT3
test_last.c: In function âmainâ:
test_last.c:15:46: error: âiiâ appears more than once in data clauses
 #pragma omp parallel for default(none) shared(ii) firstprivate(ii) lastprivate(ii)
                                              ^
% gcc -fopenmp test_last.c 

% pgcc -mp test_last.c -DOPT1
% pgcc -mp test_last.c -DOPT2
% pgcc -mp test_last.c -DOPT3
% pgcc -mp test_last.c 
PGC-S-0155-ii must appear in a SHARED or PRIVATE clause (test_last.c: 27)
PGC/x86-64 Linux Rel Dev-r113589: compilation completed with severe errors

Yeah, I took a look at the OpenMP standard and this is the first time I’ve ever realized you can do a firstprivate and lastprivate at the same time for a variable. Makes sense, but I just never thought to do it.

I think the simplest work around would be to remove the “default(none)”.

Well, simpler for me might be to compile NCO without OpenMP for now. I mean, I’m not sure I know of anyone around here using the threaded bits. If nothing else, this will let me know if someone does if they can’t do it anymore!

Thanks,
Matt