In fact `loadLibrary ""` doesn't work on Darwin, `loadExecutable ()` is required.

Phil

On 11/09/18 21:50, Phil Clayton wrote:
Looking at polyffi.cpp it actually looks like `loadLibrary ""` ends up calling
   dlopen ("", ...)
whereas `loadExecutable ()` ends up calling
   dlopen (NULL, ...)
A couple of things I have read suggest that these often give the same result, if not always.  So for non-Windows platforms `loadLibrary ""` and `loadExecutable ()` look similar.  However, the dlopen man page doesn't mention the empty string case, so it seems preferable to use `loadExecutable ()` over `loadLibrary ""`.

For Windows, I don't know what LoadLibrary("") does.  So again it seems preferable to use `loadExecutable ()` over `loadLibrary ""`.

Phil

On 11/09/18 04:15, Kostirya wrote:
Hello.
What is the difference between (LoadLibrary "") and (loadExecutable ()) calls?

2018-09-10 17:53 GMT+03:00 Phil Clayton <phil.clay...@veonix.com>:
Slight correction: using an empty string for the library has the effect of passing NULL to dlopen which means the handle passed to dlsym is the current
program.


On 10/09/18 15:29, Phil Clayton wrote:

Hi Mark,

  > (* symbol lookup error: /usr/lib/x86_64-linux-gnu/libgsl.so: undefined
  > symbol: cblas_dgemm *)

To avoid looking for the symbol "cblas_dgemm" in libgsl (which doesn't
define it), you could let the dynamic linker look for it by using an empty
string for the library which has the effect of passing RTLD_DEFAULT to
dlsym.

    val gsl = loadLibrary "";

To make sure these libraries are searched, you would need to start your
poly session with something like


LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libgsl.so":"/usr/lib/x86_64-linux-gnu/libgslcblas.so
\
    poly

which could be put into a wrapper script.  Or you could build an
executable (which could be a poly REPL) and link to them.

Another advantage of this approach is portability.  The SML code is more portable because shared object names and their paths vary across systems. Linking also avoids the problem of specifying the library names because you use flags such as -lgsl and the linker works it out. Linking can be done in an even more portable way using a utility like pkg-config to generate the
linker arguments:

    pkg-config --libs gsl

(This usual requires the -devel or -dev package for the library.)

Regards,
Phil


On 09/09/18 21:15, Mark Clements wrote:

I am enjoying using polyml's Foreign structure.

However, in using the GNU Scientific Library (GSL), I have run into a
problem with linkage. The GSL library (libgsl.so) calls standard cBLAS
matrix functions with unknown symbols to allow the user to link with
different cBLAS implementations (NB: GSL provides an unoptimised cBLAS
implementation named libgslcblas.so). When I call a GSL function that
depends on the cBLAS functions, I get a symbol not defined error.

I have tried unsuccessfully (a) loading the libgslcblas library either
before or after loading libgsl, (b) changing the loadLibrary
implementation to use dlopen with RTLD_LAZY | RTLD_GLOBAL, and (c)
compiling the SML code to an object file and then linking against the
libraries.

How could this be made to work?

Sincerely, Mark.

PS test code for (a) is:

open Foreign;
val gsl = loadLibrary "/usr/lib/x86_64-linux-gnu/libgsl.so";
val gslcblas = loadLibrary "/usr/lib/x86_64-linux-gnu/libgslcblas.so";
type gsl_matrix_t = Memory.voidStar; (* for demonstration only *)
local
      val call1 =    buildCall2((getSymbol gsl "gsl_matrix_calloc"),
(cInt,cInt), cPointer)
      val call2 =    buildCall4((getSymbol gsl "gsl_matrix_set"),
(cPointer,cInt,cInt,cDouble), cVoid)
      val call3 =    buildCall3((getSymbol gsl
"gsl_linalg_exponential_ss"), (cPointer, cPointer, cDouble), cVoid)
in
fun gsl_matrix_alloc (size1,size2) = call1(size1,size2)
fun gsl_matrix_set (ptr : gsl_matrix_t, i, j, x) = call2(ptr, i, j, x)
fun gsl_matrix (arr : real Array2.array) =
      let
      val size1 = Array2.nRows arr
      val size2 = Array2.nCols arr
      val ptr = gsl_matrix_alloc(size1, size2)
      val _ = Array2.tabulate Array2.RowMajor (size1, size2, fn (i,j) =>
gsl_matrix_set(ptr, i, j, Array2.sub(arr, i, j)))
      in
      ptr
      end
fun gsl_mexp (arr : real Array2.array) =
      let
      val size1 = Array2.nRows arr
      val size2 = Array2.nCols arr
      val ptr = gsl_matrix arr
      val ptr2 = gsl_matrix_alloc(size1, size2)
      val _ = call3(ptr, ptr2, 0.01)
      in
      ptr2
      end
end;
fun main() =
      let
      val a = Array2.fromList [[1.0,2.0],[3.0,4.0]];
      val ptr = gsl_matrix(a);
      val m = gsl_mexp(a) (* fails *)
      in
      ()
      end;
(* symbol lookup error: /usr/lib/x86_64-linux-gnu/libgsl.so: undefined
symbol: cblas_dgemm *)

For (c):

polyc -c test.sml
g++ test.o -L/usr/lib/x86_64-linux-gnu -lgsl -lgslcblas `pkg-config
--libs polyml`
./a.out
# same error
_______________________________________________
polyml mailing list
polyml@inf.ed.ac.uk
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml

_______________________________________________
polyml mailing list
polyml@inf.ed.ac.uk
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml

_______________________________________________
polyml mailing list
polyml@inf.ed.ac.uk
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml


_______________________________________________
polyml mailing list
polyml@inf.ed.ac.uk
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml

_______________________________________________
polyml mailing list
polyml@inf.ed.ac.uk
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml

Reply via email to