Re: error loading cxx local model in isis: undefined symbol

From: John Houck <houck_at_email.domain.hidden>
Date: Tue, 19 Nov 2013 13:40:12 -0500
On Tue, Nov 19, 2013 at 11:06 -0500, Thomas Dauser wrote:
> Hi John,
> 
> thanks for your reply. Still, I'm confused. I'm trying to understand
> why local models in C are so much more complicated for isis than in
> xspec.

The fundamental issue here is that xspec is a C++ program
and isis is a C program.

If you write a C++ local model that takes arguments defined in
terms of C++ constructs such as references to templated arrays,
then xspec can use that interface directly, but a C program
such as isis cannot.

To make it work, a C-linkage interface must be provided.
This interface must be defined purely in terms of C constructs
such as double *, int, char *, etc.

Xspec has defined a set of conventions for the naming of
C, Fortran and C++ symbols and how those symbols are related
to what goes into the lmodel.dat file.

So to get an xspec local model to work with isis, the only
requirement is that the xspec local model provide either a
C or a fortran linkage symbol for isis to load.

"provide a C linkage symbol" means "provide a subroutine
with an interface that a C program can call".

> 
> I got the C++ model running, exactly as you described. Is there a
> reason why one has to write a wrapper for isis, which is done by
> xspec automatically. 

I don't know if xspec does this automatically or not.  I didn't
actually read the xspec documentation -- I'm just describing
what's needed to make it work.

However, looking at the symbols in the libxspeclocal.so file, I
see only one symbol generated for a C++ subroutine and I see no
C or Fortran linkage symbols, auto-generated or otherwise.

So it doesn't appear that xspec is automatically generating
these other wrappers.  Presumably it could, but it doesn't seem
to be.

> But not the way I understood it from Maurice, although this
> approach made much more sense in my opinion. Now I have to
> define a C++ model with
> 
> extern "C" test void( ... )

The extern "C" part just means "don't put a C++ mangled name in
the shared library file, use a plain vanilla name instead".

More importantly, note that the parameters being passed to the
'test' function are C++ specific references to templated
arrays. A C interface can't deal directly with those C++
constructs.

[...]
> Please tell me, if I'm completely missing something or just
> completely underestimate the complexity of importing local xspec
> models into isis. Thanks!

I don't think there's any additional complexity, or if there is
additional complexity, it has nothing to do with isis.  It's
just a matter of providing interfaces with the correct linkage.

If xspec automatically generates the C linkage symbols,
that's great.  If not, then the user must provide them.

Many xspec models are implemented in C++ and both C and Fortran
interfaces are provided for all of them.  They all work this
way and isis uses the same code to find symbols for the xspec
built-in models as it does to find symbols for local models.

If xspec local models somehow work differently than xspec
built-in models, then I would have to introduce additional
complexity into isis to deal with that.

Thanks,
-John

> 
> 
> Cheers,
> Thomas
> 
> On 11/19/2013 05:44 AM, John Houck wrote:
> >I think it's just a matter of providing an additional
> >subroutine for a C interface.
> >
> >For example, have a look at how xspec provides C and Fortran
> >interfaces for the xspec internal models. See, e.g.
> >  heasoft-6.14/Xspec/src/XSFunctions/funcWrappers.cxx
> >
> >For a C++ local model that provides a symbol 'test':
> >
> >    extern "C"
> >    void test(const RealArray& energy,
> >              const RealArray& parameter,
> >              int spectrum,
> >              RealArray& flux,
> >              RealArray& fluxError,
> >              const string& init)
> >
> >the lmodel.dat file should, by convention, refer to subroutine
> >C_test.
> >
> >The notation "C_test" means that a C++ interface is provided
> >through the symbol "test", while a C interface (if it exists)
> >should appear under the name "C_test".
> >
> >Following the examples in funcWrappers.cxx, a C-linkage symbol
> >C_test can be defined as in the appended code segment.
> >
> >Once this C-linkage symbol is provided, libxspeclocal.so will
> >contain two symbols through which the local model can be
> >evaluated. C++ programs can call 'test' and C programs can call
> >'C_test'.
> >
> >If you also want to provide a Fortran linkage symbol, then
> >funcWrappers.cxx shows one way to do that via cfortran.h. One
> >could also use the iso_c_binding module with "modern" Fortran.
> >
> >Thanks,
> >-John
> >
> >// Here's an example C-linkage wrapper definition for 'test'.
> >// An implementation of cppModelWrapper is in funcWrappers.cxx
> >// mentioned above.
> >
> >extern "C"
> >void C_test (const double* energy, int nFlux, const double* params,
> >           int spectrumNumber, double* flux, double* fluxError, const char* initStr)
> >{
> >    const size_t nPar = 3;
> >    cppModelWrapper(energy, nFlux, params, spectrumNumber, flux, fluxError,
> >                    initStr, nPar, test);
> >}
> >
> >----
> >You received this message because you are
> >subscribed to the isis-users list.
> >To unsubscribe, send a message to
> >isis-users-request_at_email.domain.hidden> >with the first line of the message as:
> >unsubscribe
> >

----
You received this message because you are
subscribed to the isis-users list.
To unsubscribe, send a message to
isis-users-request_at_email.domain.hiddenwith the first line of the message as:
unsubscribe
Received on Tue Nov 19 2013 - 13:40:45 EST

This archive was generated by hypermail 2.2.0 : Wed Nov 20 2013 - 05:29:18 EST