[gmx-developers] unbundling the lmfit library bundled with Gromacs

Dominik 'Rathann' Mierzejewski dominik at greysector.net
Tue Nov 24 01:52:27 CET 2015


Dear Developers,
I am the maintainer of the GROMACS package in Fedora. Recently, I found
that GROMACS bundles the lmfit library
(http://apps.jcns.fz-juelich.de/doku/sc/lmfit), which is already packaged
in Fedora (https://apps.fedoraproject.org/packages/lmfit). However, it
seems that the GROMACS-included version is modified from latest 5.1
version (cleaned-up patch showing the main differences attached) and in
a bad way: it breaks API and ABI (lmcurve_evaluate() and lmcurve()).

Now, this can be done properly by introducing new API that GROMACS can
use while keeping the existing API intact. To that end, I'm attaching
a patch that tries to do just that. I'm not claiming my solution is the
best or even entirely correct, but it should be a start.

I'm also attaching an initial patch for GROMACS to use a system-wide
shared library with this new API. It's most probably not suitable
to be applied as-is, but at least the internal test suite (make check)
passes.

I'm Cc'ing other interested parties, including the Fedora lmfit package
maintainer (Miro), the lmfit author (Joachim Wuttke) and Tobias Klauser,
who seems to have created a fork of lmfit on github
(https://github.com/tklauser/lmfit) which contains at least one fix
present in GROMACS fork of lmfit, too (the memleak fix:
https://github.com/tklauser/lmfit/commit/1dfe71ae26986b52e6037fb1933904d541ab100f).

Regards,
Dominik
-- 
Fedora http://fedoraproject.org/wiki/User:Rathann
RPMFusion http://rpmfusion.org
"Faith manages."
        -- Delenn to Lennier in Babylon 5:"Confessions and Lamentations"
-------------- next part --------------
diff -ruwbBd /home/rathann/build/SOURCES/lmfit/lmfit-5.1/lib/lmcurve.c lmfit-gromacs/lmcurve.c
--- /home/rathann/build/SOURCES/lmfit/lmfit-5.1/lib/lmcurve.c	2013-07-31 06:34:47.000000000 +0200
+++ lmfit-gromacs/lmcurve.c	2015-11-24 01:34:51.643717969 +0100
@@ -14,28 +14,32 @@
 
 #include "lmmin.h"
 
+#include "gromacs/utility/basedefinitions.h"
 
 typedef struct {
     const double *t;
     const double *y;
+    const double *dy;
     double (*f) (double t, const double *par);
 } lmcurve_data_struct;
 
 
 void lmcurve_evaluate( const double *par, int m_dat, const void *data,
-                       double *fvec, int *info )
+                       double *fvec, gmx_unused int *info )
 {
     int i;
+    double fy;
+    lmcurve_data_struct *d = (lmcurve_data_struct*) data;
     for ( i = 0; i < m_dat; i++ )
-        fvec[i] =
-            ((lmcurve_data_struct*)data)->y[i] -
-            ((lmcurve_data_struct*)data)->f(
-                ((lmcurve_data_struct*)data)->t[i], par );
+    {
+        fy      = d->f(d->t[i], par );
+        fvec[i] = (d->y[i] - fy)/d->dy[i];
+    }
 }
 
 
 void lmcurve( int n_par, double *par, int m_dat, 
-              const double *t, const double *y,
+              const double *t, const double *y, const double *dy,
               double (*f)( double t, const double *par ),
               const lm_control_struct *control,
               lm_status_struct *status )
@@ -43,6 +47,7 @@
     lmcurve_data_struct data;
     data.t = t;
     data.y = y;
+    data.dy = dy;
     data.f = f;
 
     lmmin( n_par, par, m_dat, (const void*) &data,
diff -ruwbBd /home/rathann/build/SOURCES/lmfit/lmfit-5.1/lib/lmcurve.h lmfit-gromacs/lmcurve.h
--- /home/rathann/build/SOURCES/lmfit/lmfit-5.1/lib/lmcurve.h	2013-08-19 10:05:13.000000000 +0200
+++ lmfit-gromacs/lmcurve.h	2015-11-24 01:35:26.104042093 +0100
@@ -29,7 +29,7 @@
 __BEGIN_DECLS
 
 void lmcurve( int n_par, double *par, int m_dat,
-              const double *t, const double *y,
+              const double *t, const double *y, const double *dy,
               double (*f)( double t, const double *par ),
               const lm_control_struct *control,
               lm_status_struct *status );
-------------- next part --------------
diff -up lmfit-5.1/lib/lmcurve.c.gromacs lmfit-5.1/lib/lmcurve.c
--- lmfit-5.1/lib/lmcurve.c.gromacs	2013-07-31 06:34:47.000000000 +0200
+++ lmfit-5.1/lib/lmcurve.c	2015-11-23 23:35:08.360570218 +0100
@@ -19,6 +19,7 @@ typedef struct {
     const double *t;
     const double *y;
     double (*f) (double t, const double *par);
+    const double *dy;
 } lmcurve_data_struct;
 
 
@@ -33,6 +34,19 @@ void lmcurve_evaluate( const double *par
                 ((lmcurve_data_struct*)data)->t[i], par );
 }
 
+void lmcurve_evaluate_d( const double *par, int m_dat, const void *data,
+                       double *fvec, int *info )
+{
+    int i;
+    double fy;
+    lmcurve_data_struct *d = (lmcurve_data_struct*) data;
+    for ( i = 0; i < m_dat; i++ )
+    {
+        fy      = d->f(d->t[i], par);
+        fvec[i] = (d->y[i] - fy)/d->dy[i];
+    }
+}
+
 
 void lmcurve( int n_par, double *par, int m_dat, 
               const double *t, const double *y,
@@ -43,8 +57,25 @@ void lmcurve( int n_par, double *par, in
     lmcurve_data_struct data;
     data.t = t;
     data.y = y;
+    data.dy = NULL;
     data.f = f;
 
     lmmin( n_par, par, m_dat, (const void*) &data,
            lmcurve_evaluate, control, status );
 }
+
+void lmcurve_d( int n_par, double *par, int m_dat, 
+              const double *t, const double *y, const double *dy,
+              double (*f)( double t, const double *par ),
+              const lm_control_struct *control,
+              lm_status_struct *status )
+{
+    lmcurve_data_struct data;
+    data.t = t;
+    data.y = y;
+    data.dy = dy;
+    data.f = f;
+
+    lmmin( n_par, par, m_dat, (const void*) &data,
+           lmcurve_evaluate_d, control, status );
+}
diff -up lmfit-5.1/lib/lmcurve.h.gromacs lmfit-5.1/lib/lmcurve.h
--- lmfit-5.1/lib/lmcurve.h.gromacs	2013-08-19 10:05:13.000000000 +0200
+++ lmfit-5.1/lib/lmcurve.h	2015-11-23 23:23:41.826040263 +0100
@@ -34,5 +34,11 @@ void lmcurve( int n_par, double *par, in
               const lm_control_struct *control,
               lm_status_struct *status );
 
+void lmcurve_d( int n_par, double *par, int m_dat,
+              const double *t, const double *y, const double *dy,
+              double (*f)( double t, const double *par ),
+              const lm_control_struct *control,
+              lm_status_struct *status );
+
 __END_DECLS
 #endif /* LMCURVE_H */
-------------- next part --------------
diff -up gromacs-5.1.1/src/gromacs/CMakeLists.txt.lmfit gromacs-5.1.1/src/gromacs/CMakeLists.txt
--- gromacs-5.1.1/src/gromacs/CMakeLists.txt.lmfit	2015-10-30 12:06:59.000000000 +0100
+++ gromacs-5.1.1/src/gromacs/CMakeLists.txt	2015-11-24 00:31:50.086104275 +0100
@@ -202,6 +202,7 @@ target_link_libraries(libgromacs
                       ${GMX_EXTRA_LIBRARIES}
                       ${TNG_IO_LIBRARIES}
                       ${FFT_LIBRARIES} ${LINEAR_ALGEBRA_LIBRARIES}
+                      ${LMFIT_LIBRARIES}
                       ${XML_LIBRARIES}
                       ${THREAD_LIB} ${GMX_SHARED_LINKER_FLAGS} ${OPENCL_LIBRARIES})
 set_target_properties(libgromacs PROPERTIES
diff -up gromacs-5.1.1/src/gromacs/correlationfunctions/CMakeLists.txt.lmfit gromacs-5.1.1/src/gromacs/correlationfunctions/CMakeLists.txt
--- gromacs-5.1.1/src/gromacs/correlationfunctions/CMakeLists.txt.lmfit	2015-06-22 15:17:54.000000000 +0200
+++ gromacs-5.1.1/src/gromacs/correlationfunctions/CMakeLists.txt	2015-11-24 00:32:27.762892299 +0100
@@ -33,9 +33,10 @@
 # the research papers on the package. Check out http://www.gromacs.org.
 
 file(GLOB GMXCORRFUNC_SOURCES *.c *.cpp)
-file(GLOB LMFIT_SOURCES ${CMAKE_SOURCE_DIR}/src/external/lmfit/*.c)
 
-set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${GMXCORRFUNC_SOURCES}  ${LMFIT_SOURCES} PARENT_SCOPE)
+find_library(LMFIT_LIBRARIES lmfit)
+
+set(LIBGROMACS_SOURCES ${LIBGROMACS_SOURCES} ${GMXCORRFUNC_SOURCES} PARENT_SCOPE)
 if (BUILD_TESTING)
     add_subdirectory(tests)
 endif()
diff -up gromacs-5.1.1/src/gromacs/correlationfunctions/expfit.cpp.lmfit gromacs-5.1.1/src/gromacs/correlationfunctions/expfit.cpp
--- gromacs-5.1.1/src/gromacs/correlationfunctions/expfit.cpp.lmfit	2015-06-22 15:17:54.000000000 +0200
+++ gromacs-5.1.1/src/gromacs/correlationfunctions/expfit.cpp	2015-11-23 23:52:32.887804562 +0100
@@ -51,7 +51,7 @@
 
 #include <algorithm>
 
-#include "external/lmfit/lmcurve.h"
+#include <lmcurve.h>
 
 #include "gromacs/correlationfunctions/integrate.h"
 #include "gromacs/fileio/xvgr.h"
@@ -482,7 +482,7 @@ static gmx_bool lmfit_exp(int          n
     do
     {
         ochisq = chisq;
-        lmcurve(nparam, parm, nfit, x, y, dy,
+        lmcurve_d(nparam, parm, nfit, x, y, dy,
                 lmcurves[eFitFn], &control, status);
         chisq = sqr(status->fnorm);
         if (bVerbose)


More information about the gromacs.org_gmx-developers mailing list