Nvlink error : Multiple definition of 'nvkernel__...'

Hello all,

I am struggling with nvlink error (no issue with the crayCC compiler):

nvlink error : Multiple definition of ‘nvkernel__ZN10TRUSTArrayIdEaSEd_F383L576_1’ in ‘/export/home/catA/pl254994/trust/amgx_openmp/lib/TRUST_mpi.a:distances_EF.cpp.o’, first defined in ‘/export/home/catA/pl254994/trust/amgx_openmp/lib/TRUST_mpi.a:Domaine_EF_axi.cpp.o’
nvlink fatal : merge_elf failed
pgacclnk: child process exit status 2: /export/home/catA/pl254994/.tmp_TRUST_trust/nvhpc-22.1/Linux_x86_64/22.1/compilers/bin/tools/nvdd

The related code is:

#pragma omp declare target
template <typename _TYPE_>
TRUSTArray<_TYPE_>& TRUSTArray<_TYPE_>::operator=(_TYPE_ x)
{
  const int n = size_array_;
  _TYPE_ *data = data_;
#ifdef _OPENMP
  bool dataOnDevice = isDataOnDevice(*this);
  #pragma omp target teams distribute parallel for if (dataOnDevice)
#endif
  for (int i = 0; i < n; i++) data[i] = x;
  return *this;
}
#pragma omp end declare target

How can I avoid the kernel is defined multiple times ?

Thanks

Hi Pierre,

I’m not sure. I’ve tried to reproduce this will smaller examples but haven’t been able to get a multiply defined reference error.

Can you walk me through the steps you did when building AMGx so I can try and reproduce it?

Also, can you try installing our 23.1 compilers just in case the behavior has changed?

-Mat

Hello Mat,

The issue is not related to AmgX (even though the name appears in the path). After some tests, it seems that the multiple definition of nvkernel appears when an OpenMP kernel is written in a template function implemented in a include file. So I moved the template implementation (with the OpenMP Kernel) in a .cpp file and it solved my issue. Guess that the nvc++ linker struggles when inlining several times OpenMP kernel from a template function… Sorry for not providing a code sample to reproduce the issue. I will try with a more recent compiler when I will have more time than now,
Thanks again,

Pierre