Re: Call native wrapper function with double argument
Hi Thorsten, welcome back! :) > I'm playing around with the native function again (after a long long time > ;-) and somehow I don't manage to call a native wrapper with double arg. > > Using rmath from R, random value from poisson distribution:^ > ## double› rpois(double); > ... > This works > : (native "libRmath.so" "rpois" 1.0 (2.567 . 1.0)) > ... > but this dumps > : (de rpois (X) (native "libRmath.so" "rpois" 1.0 (X . 1.0) ) ) > ... > When I debug it, X=3 when the function is called. The problem is (X . 1.0), it calls 'X' as a function. So this would work: : (de rpois (X) (native "libRmath.so" "rpois" 1.0 (cons X 1.0) ) ) ☺/ A!ex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Call native wrapper function with double argument
Hi Alex, yes that works with (cons X 1.0), I knew it was a trivial problem. Thanks! Cheers Thorsten Am Fr., 13. Nov. 2020 um 08:00 Uhr schrieb Alexander Burger < a...@software-lab.de>: > Hi Thorsten, > > welcome back! :) > > > I'm playing around with the native function again (after a long long time > > ;-) and somehow I don't manage to call a native wrapper with double arg
Re: Call native wrapper function with double argument
Hi Alex, one more question: (de pwilcox (X Y Z I J) (! native `*LibRmath "pwilcox" 1.0 (cons X 1.0) (cons Y 1.0) (cons Z 1.0) I J ) ) ## double pwilcox(double, double, double, int, int); : (rmath~pwilcox 2.7 6.20 5.4 1 3) (native "libRmath.so" "pwilcox" 1 (cons X 1) (cons Y 1) (cons Z 1) I "J") ! J -> NIL ! I -> 1 ! -> -4 Why is that second Integer argument interpreted as transient symbol, and then NIL although the actual arg = 3? In the docs I only find: "The number of fixpoint arguments is limited to six." but that looks irrelevant here. So how do I specify a ## double pwilcox(double, double, double, int, int); signature correctly? Cheers Thorsten Am Fr., 13. Nov. 2020 um 17:15 Uhr schrieb Thorsten Jolitz < tjol...@gmail.com>: > Hi Alex, > yes that works with (cons X 1.0), I knew it was a trivial problem. > Thanks! > Cheers > Thorsten > > Am Fr., 13. Nov. 2020 um 08:00 Uhr schrieb Alexander Burger < > a...@software-lab.de>: > >> Hi Thorsten, >> >> welcome back! :) >> >> > I'm playing around with the native function again (after a long long >> time >> > ;-) and somehow I don't manage to call a native wrapper with double arg. >> >> > >> > Using rmath from R, random value from poisson distribution:^ >> > ## double› rpois(double); >> > ... >> > This works >> > : (native "libRmath.so" "rpois" 1.0 (2.567 . 1.0)) >> > ... >> > but this dumps >> > : (de rpois (X) (native "libRmath.so" "rpois" 1.0 (X . 1.0) ) ) >> > ... >> > When I debug it, X=3 when the function is called. >> >> The problem is (X . 1.0), it calls 'X' as a function. >> >> So this would work: >> >>: (de rpois (X) >> (native "libRmath.so" "rpois" 1.0 (cons X 1.0) ) ) >> >> ☺/ A!ex >> >> -- >> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe >> >>
Re: Call native wrapper function with double argument
Hi Thorsten, > (de pwilcox (X Y Z I J) > ... > : (rmath~pwilcox 2.7 6.20 5.4 1 3) > (native "libRmath.so" "pwilcox" 1 (cons X 1) (cons Y 1) (cons Z 1) I "J") > ... > ! J > -> NIL > Why is that second Integer argument interpreted as transient symbol, and > then NIL although the actual arg = 3? This is strange. I tried the same here, and get (native NIL "pwilcox" 100 (cons X 100) (cons Y 100) (cons Z 100) I J) And I get 3 as expected for 'J'. Note the scaled integers! It seems your *Scl is zero. But this does not explain what you see. Are you sure you pasted exactly what you tested? > In the docs I only find: > "The number of fixpoint arguments is limited to six." > but that looks irrelevant here. Yes, for pil64. For pil21 this no longer holds. There is no more limit on the number of float or double arguments. ☺/ A!ex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Call native wrapper function with double argument
Hi Alex, this is strange indeed. I checked on Bash/Archlinux as well, same problem as Win Term / WSL2, so this is not about WSL or so. I can like you define a dummy wrapper, and debug it, and it looks fine: : (de foo (I J) (! native NIL NIL 1.0 I J)) -> foo : (foo 2 3) (native NIL NIL 1 I J) ! J -> 3 So here I can use J as argument name, and it works. But with my real wrapper functions, where ever I use J, as first or second arg, its interpreted as a transient symbol and is NIL, even if I create a fake wrapper without any real lib reference: : (rmath~exp_rand_fake2 3 2) (native NIL NIL 1 "J" B) ! J -> NIL But when I rename J to H in my real wrapper function, the problem is gone: : (rmath~pwilcox 1.2 2.1 3.2 3 2) (native "libRmath.so" "pwilcox" 1 (cons X 1) (cons Y 1) (cons Z 1) I H) ! H -> 2 So I think I know whats the problem here: its reading the function definitions from a library file vs defining the definition directly in the repl. (load "libRmath.l") seems to have a problem with the char J used for a paramter, and somehow converts it into a transient symbol. The easy solution is therefore to avoid J as parameter name ;-) But maybe I found a bug? Cheers Thorsten Am So., 15. Nov. 2020 um 09:01 Uhr schrieb Alexander Burger < a...@software-lab.de>: > Hi Thorsten, > > > (de pwilcox (X Y Z I J) > > ... > > : (rmath~pwilcox 2.7 6.20 5.4 1 3) > > (native "libRmath.so" "pwilcox" 1 (cons X 1) (cons Y 1) (cons Z 1) I "J") > > ... > > ! J > > -> NIL > > Why is that second Integer argument interpreted as transient symbol, and > > then NIL although the actual arg = 3? > > This is strange. I tried the same here, and get > >(native NIL "pwilcox" 100 (cons X 100) (cons Y 100) (cons Z > 100) I J) > > And I get 3 as expected for 'J'. > > Note the scaled integers! It seems your *Scl is zero. But this does not > explain > what you see. Are you sure you pasted exactly what you tested? > > > > In the docs I only find: > > "The number of fixpoint arguments is limited to six." > > but that looks irrelevant here. > > Yes, for pil64. For pil21 this no longer holds. There is no more limit on > the > number of float or double arguments. > > ☺/ A!ex > > -- > UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe >
Re: Call native wrapper function with double argument
Hi Thorsten, > But with my real wrapper functions, where ever I use J, as first or second > arg, its interpreted as a transient symbol So somewhere 'J' is bound to "J". > But when I rename J to H in my real wrapper function, the problem is gone: Right, so it is a binding issue. Think hard what values are exactly bound to which variables at runtime. Such things happen usually only in FEXPRs or when evaluable expressions are passed around through binding environments. > So I think I know whats the problem here: its reading the function > definitions from a library file vs defining the definition directly in the > repl. > (load "libRmath.l") seems to have a problem with the char J used for a Is "libRmath.l" written by you? > The easy solution is therefore to avoid J as parameter name ;-) > But maybe I found a bug? I don't think it is a bug. But you must take care of the implications of dynamic binding, exwlained e.g. in: https://software-lab.de/doc/faq.html#problems Such things are best fixed with transient or private symbols, or even a separate namespace. ☺/ A!ex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Call native wrapper function with double argument
On Sun, Nov 15, 2020 at 06:44:20PM +0100, Alexander Burger wrote: > So somewhere 'J' is bound to "J". > ... > Right, so it is a binding issue. Think hard what values are exactly bound to > which variables at runtime. I forgot to add: You can perhaps see what is happening, by inspecting a backtrace with (bt) at the breakpoint. ☺/ A!ex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Call native wrapper function with double argument
Hi Alex, I actually do use a namespace, and there is not much going on wrt to assignments: >From line 8 on there are only some 100+ mostly trivial wrapper functions, see PS. I first thought it might have something to do with Picolisp Linebreaks "delta J", but I have seen the same issue now with an Y parameter name, not just J. With a definition like in PS 1, I would be on the safe side? When I use (bt) on the original signature specification, it looks like this: (native NIL "pwilcox" 1000 (cons X 1000) (cons Y 1000) (cons Z 1000) I "J") ! (bt) ("pwilcox" 2700 6200 2100 3 ..) X 2700 Y 6200 Z 2100 I 3 "J" 2 Cheers Thorsten PS 1 (de pnorm_both ("X" "Y" "Z" "I" "J") (! native `*LibRmath "pnorm_both" 1.0 (cons "X" 1.0) '("Y" (1.0 . 4)) '("Z" (1.0 . 4)) "I" "J" ) ) ## void›pnorm_both(double, double *, double *, int, int);/* both tails */ : (rmath~pnorm_both 2.1 3.2 4.1 3 2) (native "libRmath.so" "pnorm_both" NIL (cons "X" 1000) '("Y" (1000 . 4)) '("Z" (1000 . 4)) "I" "J") ! (bt) ("pnorm_both" 2100 3200 4100 3 ..) "X" 2100 "Y" 3200 "Z" 4100 "I" 3 "J" 2 PS 2 1 # libRmath.l - (native) PicoLisp bindings for Rmath 2 # copyright (C) 2020 Thorsten Jolitz 3 4 (symbols 'rmath 'pico) 5 6 (default *LibRmath "libRmath.so") 7 8 (de Rlog1p (X) 9 (native `*LibRmath "Rlog1p" 1.0 (cons X 1.0) ) ) 10 ## double Rlog1p(double); Am So., 15. Nov. 2020 um 18:50 Uhr schrieb Alexander Burger < a...@software-lab.de>: > Hi Thorsten, > > > But with my real wrapper functions, where ever I use J, as first or > second > > arg, its interpreted as a transient symbol > > So somewhere 'J' is bound to "J". > > > > But when I rename J to H in my real wrapper function, the problem is > gone: > > Right, so it is a binding issue. Think hard what values are exactly bound > to > which variables at runtime. Such things happen usually only in FEXPRs or > when > evaluable expressions are passed around through binding environments. > > > > So I think I know whats the problem here: its reading the function > > definitions from a library file vs defining the definition directly in > the > > repl. > > (load "libRmath.l") seems to have a problem with the char J used for a > > Is "libRmath.l" written by you? > > > > The easy solution is therefore to avoid J as parameter name ;-) > > But maybe I found a bug? > > I don't think it is a bug. But you must take care of the implications of > dynamic > binding, exwlained e.g. in: > >https://software-lab.de/doc/faq.html#problems > > Such things are best fixed with transient or private symbols, or even a > separate > namespace. > > ☺/ A!ex > > -- > UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe > >
Re: Call native wrapper function with double argument
Hi Thorsten, hmm, this is not correct: > (de pnorm_both ("X" "Y" "Z" "I" "J") > (! native `*LibRmath "pnorm_both" 1.0 (cons "X" 1.0) '("Y" (1.0 . 4)) > '("Z" (1.0 . 4)) "I" "J" ) ) "Z" is an argument to the function, so it is bound to some evaluated value. But this value is ignored, because in '("Z" (1.0 . 4)) "Z" is a *return* value. Also, (1.0 . 4) makes no sense here. A structure argument is '(Var ( . mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Call native wrapper function with double argument
Hi Alex, the wrappers with primitive arguments do work now when defined like this with transient symbols: (de pgamma ("X" "Y" "Z" "I" "J") (native `*LibRmath "pgamma" 1.0 (cons "X" 1.0) (cons "Y" 1.0) (cons "Z" 1.0) "I" "J" ) ) ## double› pgamma(double, double, double, int, int); With your tips I could define wrappers for functions with pointer args too (de pnorm_both ("X" "I" "J") (use "Y" "Z" (native `*LibRmath "pnorm_both" NIL (cons "X" 1.0) '("Y" (8 . 1.0)) '("Z" (8 . 1.0)) "I" "J" ) (list "Y" "Z") ) ) ## void›pnorm_both(double, double *, double *, int, int);/* both tails */ does work (scl 3): : (rmath~pnorm_both 1.2 2 3) -> (-122 -2162) now I only have to understand the meaning of some of these functions. What I find irritating is that the pointer args are not used for input but only as a kind of return values. Thanks for your help! Cheers Thorsten Am So., 15. Nov. 2020 um 22:55 Uhr schrieb Alexander Burger < a...@software-lab.de>: > Hi Thorsten, > > hmm, this is not correct: > > > (de pnorm_both ("X" "Y" "Z" "I" "J") > > (! native `*LibRmath "pnorm_both" 1.0 (cons "X" 1.0) '("Y" (1.0 . 4)) > > '("Z" (1.0 . 4)) "I" "J" ) ) > > "Z" is an argument to the function, so it is bound to some evaluated value. > > But this value is ignored, because in > >'("Z" (1.0 . 4)) > > "Z" is a *return* value. Also, (1.0 . 4) makes no sense here. A structure > argument is > >'(Var ( . > but 1.0 is no size (it is too big, something like 100) and 4 is no > return > spec. > > > If you want to pass a buffer to receivea double (the double* in the C > signature), you would do: > >(use MyDouble > (native `*LibRmath "pnorm_both" 1.0 ... > '(MyDouble (8 . 1.0)) ... ) > ... do something with MyDouble ...) > > (8 . 1.0) allocates 8 bytes on the stack, passes the pointer to the C > function, > receives a double in this place, and stores it in the symbol MyDouble. > > ☺/ A!ex > > -- > UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe >
Re: Call native wrapper function with double argument
Hi Alex, one more 'native' question, this time a bit more complicated: libblas.so is on my machine, the C function "idamax_" is found,which is actually a C wrapper for Fortran Code. In the Fortran docs, the parameters are described exactly, see below. Since the Parameters of the C function are input/output Parameters, I try to define the input values in the CDDR, but obviously not correctly. How do I define an input array correctly (especially DX and INCX)? If I have in/out Parameters, how do I get the int return value too when the pil functions returns? hope these questions are not too messy ... cheers Thorsten PS when I understand how this works, I will use the input values for native as parameters for the pil wrapper, but for now I just write them inside of 'native'. *> \param[in] N 33 *> \verbatim 34 *> N is INTEGER 35 *> number of elements in input vector(s) 36 *> \endverbatim 37 *> 38 *> \param[in] DX 39 *> \verbatim 40 *> DX is DOUBLE PRECISION array, dimension ( 1 + ( N - 1 )*abs( INCX ) ) 41 *> \endverbatim 42 *> 43 *> \param[in] INCX 44 *> \verbatim 45 *> INCX is INTEGER 46 *> storage spacing between elements of DX 47 *> \endverbatim 48 * (symbols 'blas 'pico) (default *LibBlas "libblas.so") (de idamax () (use "N" "Dx" "Incx" (native `*LibBlas "idamax_" 'I '("N" (4 . 'I) 3) '("Dx" (8 . 1.0) '(1.0 1 2 3)) '("Incx" (4 . 'I) 0))(list "N" "Dx" "Incx") ) ) ## BLAS_extern int/* IDAMAX - return the index of the element with max abs value */ ## F77_NAME(idamax)(const int *n, const double *dx, const int *incx) # when INCX = 0 : (blas~idamax) -> ('NIL 0 'NIL) # when INCX = 1 segfault Am Di., 17. Nov. 2020 um 23:45 Uhr schrieb Thorsten Jolitz < tjol...@gmail.com>: > Hi Alex, > the wrappers with primitive arguments do work now when defined like this > with transient symbols: > > (de pgamma ("X" "Y" "Z" "I" "J") >(native `*LibRmath "pgamma" 1.0 (cons "X" 1.0) (cons "Y" 1.0) (cons > "Z" 1.0) "I" "J" ) ) >## double› pgamma(double, double, double, int, int); > > With your tips I could define wrappers for functions with pointer args too > > (de pnorm_both ("X" "I" "J") > (use "Y" "Z" > (native `*LibRmath "pnorm_both" NIL (cons "X" 1.0) '("Y" (8 . > 1.0)) '("Z" (8 . 1.0)) "I" "J" ) > (list "Y" "Z") ) ) >## void›pnorm_both(double, double *, double *, int, int);/* both > tails */ > > does work (scl 3): > : (rmath~pnorm_both 1.2 2 3) > -> (-122 -2162) > > now I only have to understand the meaning of some of these functions. > What I find irritating is that the pointer args are not used for input but > only as a kind of return values. > > Thanks for your help! > Cheers > Thorsten > > Am So., 15. Nov. 2020 um 22:55 Uhr schrieb Alexander Burger < > a...@software-lab.de>: > >> Hi Thorsten, >> >> hmm, this is not correct: >> >> > (de pnorm_both ("X" "Y" "Z" "I" "J") >> > (! native `*LibRmath "pnorm_both" 1.0 (cons "X" 1.0) '("Y" (1.0 . >> 4)) >> > '("Z" (1.0 . 4)) "I" "J" ) ) >> >> "Z" is an argument to the function, so it is bound to some evaluated >> value. >> >> But this value is ignored, because in >> >>'("Z" (1.0 . 4)) >> >> "Z" is a *return* value. Also, (1.0 . 4) makes no sense here. A structure >> argument is >> >>'(Var ( . > >> but 1.0 is no size (it is too big, something like 100) and 4 is no >> return >> spec. >> >> >> If you want to pass a buffer to receivea double (the double* in the C >> signature), you would do: >> >>(use MyDouble >> (native `*LibRmath "pnorm_both" 1.0 ... >> '(MyDouble (8 . 1.0)) ... ) >> ... do something with MyDouble ...) >> >> (8 . 1.0) allocates 8 bytes on the stack, passes the pointer to the C >> function, >> receives a double in this place, and stores it in the symbol MyDouble. >> >> ☺/ A!ex >> >> -- >> UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe >> >
Re: Call native wrapper function with double argument
Hi Thorsten, > libblas.so is on my machine, the C function "idamax_" is found,which is > actually a C wrapper for Fortran Code. > In the Fortran docs, the parameters are described exactly, see below. Hmm, the signature of the C function would be more helpful, as we want to call it, and it should be exactly what needs to be known ;) But let's first fix the more obvious issues: (de idamax () (use "N" "Dx" "Incx" If more than one symbol to 'use', you need to pass a list (use ("N" "Dx" "Incx") Will not change the result though, just does not bind the symbols. BTW, there is absolutely no need to put all these symbols into transient scope. (native `*LibBlas "idamax_" 'I '("N" (4 . 'I) 3) The quote before the 'I' is wrong, because (4 ...) is not evaluated. (4 . I) will return an integer in "N", so it corresponds to 'int* n;' in C. The '3' is probaly also wrong. It initializes the 4-byte area with a *single* byte, so it depends on the endianess of the machine what it actually means, and leaves the other three bytes uninitialized. '("Dx" (8 . 1.0) '(1.0 1 2 3)) (8 . 1.0) may be good, meaning "double *dx;". The following initialization '(1.0 1 2 3) is fatal, as it initializes the 8 bytes of the memory with three double numbers. In addition, 1 2 and 3 are not double numbers. Something like '("Dx" (24 . 1.0) '(1.0 1.0 2.0 3.0)) could make sense, if the C argument is "double dx[3];". '("Incx" (4 . 'I) 0) ) Again, the quote is wrong. And it initializes the 4 bytes of the integer only with a single zero byte. (list "N" "Dx" "Incx") ) ) ☺/ A!ex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Call native wrapper function with double argument
On Mon, Nov 23, 2020 at 06:17:46PM +0100, Alexander Burger wrote: > Something like '("Dx" (24 . 1.0) '(1.0 1.0 2.0 3.0)) could make sense, if the > C > argument is "double dx[3];". oops (24 . 1.0) is of course not returning "double dx[3];", but a single double. Try (24 1.0 1.0 1.0) or better (24 (1.0 . 3)). ☺/ A!ex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Call native wrapper function with double argument
Hi Alex, thanks for your tips ... and patience! My lack of experience with C, Pointers and low level programming clearly shows in my questions, and most real world libraries of 'native' wrappers I find don't really implement complex C signatures, so I have to experiment myself. I'll try to digest your hints and do some more experimentation over the weekend. Luckily, If I manage to wrap one such C function, I can reuse that understanding for many others Cheers Thorsten Am Di., 24. Nov. 2020 um 07:50 Uhr schrieb Alexander Burger < a...@software-lab.de>: > On Mon, Nov 23, 2020 at 06:17:46PM +0100, Alexander Burger wrote: > > Something like '("Dx" (24 . 1.0) '(1.0 1.0 2.0 3.0)) could make sense, > if the C > > argument is "double dx[3];". > > oops > > (24 . 1.0) is of course not returning "double dx[3];", but a single double. > > Try (24 1.0 1.0 1.0) or better (24 (1.0 . 3)). > > ☺/ A!ex > > -- > UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe >
Re: Call native wrapper function with double argument
Hi Thorsten, > Luckily, If I manage to wrap one such C function, I can reuse that > understanding for many others Yes, and don't worry to ask. 'native' is a complex issue (I also need to look into the reference each time), so others may benefit from the records too. ☺/ A!ex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe