Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional parameters for gpufit() via function overloading not possible if we use "extern C" #39

Open
mscipio opened this issue Nov 30, 2017 · 8 comments

Comments

@mscipio
Copy link

mscipio commented Nov 30, 2017

With reference to issue #30 I have been trying lately to add an optional parameter to gpufit that is able to give you the output of the fitting in terms of time curve, that you can compare to your original data to assess also visually the quality of the result.

After some trying, I managed to find a (imho) nice way to do it through overloading of some class init function, so that, depending on the number of parameters you use when calling gpufit(), the library can understand if you want to have the output of the fitting, as well, or just the standard output argument (params, number of iterations, and so on ...)

I am having just one problem in doing it: I can overload every function I need to, and this approach is working well, a part from the actual gpufit() function!

This is due to gpufit being exposed as a C interface:

#ifdef __cplusplus
extern "C" {
#endif

Given that function overloading is a specific property of C++, you cannot use it if you want to treat gpufit() as a C function. So far I used a workaraound based on using a different alias for the gpufit() function, in case I want to call it with the additional output_data parameter. But I don't like it ...

Two questions:
1- why do you need to do the extern "C" around gpufit()? Is it required by external bindings like python or matlab?
2- if this "extern" is actually needed, do you have any idea of alternative ways to use function overloading inside the extern "C" environment?

Thanks!

@jkfindeisen
Copy link
Collaborator

jkfindeisen commented Nov 30, 2017

Is it required by external bindings like python or matlab?

Yes. For a good discussion see https://stackoverflow.com/questions/16730284/dll-written-in-c-vs-the-same-written-in-c

You could have additionally a C++ interface but only if you use the same compiler for your own project. The bindings like Python and Matlab will be limited to the extern "C" calling convention.

do you have any idea of alternative ways to use function overloading inside the extern "C" environment?

I think there are none afaik.

@jkfindeisen
Copy link
Collaborator

Btw. one workaround is SWIG. It can generate interfaces of C++ classes automatically that work as Python or Java classes but internally it uses a C interface, just automatically creates all the functions you wanted to create manually. It's support for templates is probably very limited.

See http://swig.org/Doc3.0/SWIGPlus.html#SWIGPlus

@jkfindeisen
Copy link
Collaborator

Another example of someone trying to use C++ class in Matlab for example. The idea would be the same for Python, C#, Java, .... He uses indices to a list as handles to identify classes which cannot cross the barrier. What you can do with a C interface is really, very restricted. Not even exceptions pass.

https://github.com/chappjc/MATLAB/tree/master/cppClass

@mscipio
Copy link
Author

mscipio commented Nov 30, 2017

Thanks a lot for all the links.
Working on this is becoming really instructive for me! :)

That means that, for the time being, I will decide between a separate function named slightly different than gpufit(), or an additional bool parameter with a default value (if possible in C interface) for the original gpufit() function, in order to call the other overloaded versions of class initializations ...

@superchromix
Copy link
Collaborator

We will look at this possibility. Having an alternate function call may be a viable solution.

@mscipio
Copy link
Author

mscipio commented Dec 1, 2017

I solved it using just an optional parameter to gpufit() that is defined as a pointer float * output_data but takes value NULL as default.
This is used internally as a flag to the to LMFit::get_results which data we want to transfer from GPU to CPU, keeping everything transparent if I want to keep calling gpufit() with the original 16 parameters.

If you are curious about it feel free to check my last commit to my fork!

@caowencai
Copy link

@mscipio
Also at sometimes, the output_parameters is less important than output_data through integral or
differential by the fitted model.
Under this condition, it is to save some time between GPU and CPU by hiding the output_parameters or other parameters.

@superchromix
Copy link
Collaborator

Leaving this issue open as a reminder that extending the Gpufit interface to return function values could be an option in a future release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants