acer

32333 Reputation

29 Badges

19 years, 323 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

Sorry, you are indeed wrong.

Suppose the function f is thread-unsafe, or that it calls a thread-unsafe Library routine. Then the answers computed in different Threads may partially clobber each other and then be incorrect.

A typical way for a routine to be thread-unsafe is for it to write out and store partial results in a global variable. Thread A writes a partial result, which gets overwritten by Thread B, and then Thread A accesses that variable's value so as to use the intermediary value it stored there (but which is now replaced, ooops).

In Maple, there are a delightful number of ways to "write an intermediary result, globally".

acer

Thanks, Erik, that's useful. On the one hand it's nice to know, as it increases the utility of evalhf. But on the other hand it's unfortunate, since the [] notation is less naturally safe than the :- notation. It would be simply better if evalhf supported both forms.

I once wrote some comments on the [] vs :- form for referencing module based package members. In this case, the generally safe form would be the longer Statistics[':-Mean'].

acer

Thanks, Erik, that's useful. On the one hand it's nice to know, as it increases the utility of evalhf. But on the other hand it's unfortunate, since the [] notation is less naturally safe than the :- notation. It would be simply better if evalhf supported both forms.

I once wrote some comments on the [] vs :- form for referencing module based package members. In this case, the generally safe form would be the longer Statistics[':-Mean'].

acer

Thanks. I did know that, and it was one thing that I had tried. However,

> kernelopts(version);
            Maple 12.01, X86 64 LINUX, Sep 23 2008 Build ID 363216

> p := proc(V::Vector(datatype=float[8]))
> eval(Statistics:-Mean(V));
> end proc:
> V := Vector[row]([1,2,3],datatype=float[8]):
> p(V);
                                      2.
 
> evalhf(p(V));
Error, module member referencing is not supported in evalhf

The same for 13.00, Build ID 388356.

acer

Thanks. I did know that, and it was one thing that I had tried. However,

> kernelopts(version);
            Maple 12.01, X86 64 LINUX, Sep 23 2008 Build ID 363216

> p := proc(V::Vector(datatype=float[8]))
> eval(Statistics:-Mean(V));
> end proc:
> V := Vector[row]([1,2,3],datatype=float[8]):
> p(V);
                                      2.
 
> evalhf(p(V));
Error, module member referencing is not supported in evalhf

The same for 13.00, Build ID 388356.

acer

As mentioned here, some components can be refreshed in mid-computation, in Maple 13.

For example, given embedded meter Meter0,

for i from 1 to 4 do
  DocumentTools:-SetProperty(Meter0, 'value', i*25,
                             'refresh'=true );
  st:=time[real]();
  while time[real]()-st < 2 do end do;
end do:

acer

As mentioned here, some components can be refreshed in mid-computation, in Maple 13.

For example, given embedded meter Meter0,

for i from 1 to 4 do
  DocumentTools:-SetProperty(Meter0, 'value', i*25,
                             'refresh'=true );
  st:=time[real]();
  while time[real]()-st < 2 do end do;
end do:

acer

It is interesting, that it works for you. A couple of things could be mentioned, if I may.

Your example procedure (sub1, the Maple one) is not complicated and should execute quickly.

However, if your external `sub` function will call back very many times, and if the formulae in `sub1` become very involved, then you might consider "compiling" procedure sub1 to get more speed and less symbolic garbage. By that I mean typing it appropriately and then either applying Compiler:-Compile or giving it 'option autocompile'.

When you use the WRAPPER option to define_external, Maple actually writes out a C wrapper file and compiles it to a .dll. (It might be located in a hard to find temp dir, or in the working dir -- I forget.) If you examine that .c wrapper file (before the Maple session ends and it gets deleted) you could see that it does the callback through a C function named something like `EvalMapleProc`. Autogenerated wrappers always use that mechanism for the callback, I believe. But there is also a  EvalhfDataProc that  can be used to  make the callback  use  Maple's  fast  evalhf  interpreter.  To use it, one would have to either write a custom  wrapper for define_external (possibly by heavily editing the autogenerated wrapper as a  sort of template).  But this  approach  would almost always  be slower  to run than would the simpler approach of using Compiler:-Compile.

acer

A callback (PROC) argument to define_external is only supported if the 'WRAPPER' option is also supplied, as far as I know. And the 'WRAPPER' option specifies that Maple will produce and compile a "wrapper" source file on-the-fly. (When external calling was introduced in Maple 6, that was its only mode of operation. Since then "wrapperless" external calling has been made possible using new libs maplec.dll or maplefortran.dll. But that mode doesn't support PROC.)

So, to use callbacks one must use WRAPPER, you are right. And to use WRAPPER one must have a compiler. Normally I'd say look at the free Watcom C compiler that comes bundled with Maple (and used by Compiler:-Compile). If that didn't work automagically for wrapper-generating define_external calls then one could likely set it up. See the ?COMPILE_OPTIONS help-page which seems to mention WATCOM already. But, your principal code is in Fortran.

I don't know whether the WRAPPER and FORTRAN options are supported simultaneously. (The error message you got mentioned maplec.lib which is curious.) And that seems to be key for you. If it doesn't then there may still be a way by writing and compile a custom wrapper in C (?CustomWrapper) and forming a .dll of that by hand, in advance.

Even if one worked in pure C this task seems complicated. But it may be a natural request or enhancement: Compile a Maple procedure, and then somehow pass its address to a precompiled external library of user-defined functions. (Eg, given a premade external library for global optimization or quadrature, compile the objective or integrand -- prototyped in Maple -- using Compiler:-Compile and then pass that to the external routines via define_external.)

acer

I believe that this can be done, but not so easily.

If I understand you rightly, you want to symbolically generate formulae f in Maple as Maple language code, put that into a Maple procedure, then somehow get it compiled as C or Fortran, and then make the resulting object code accessible as function sub1 and callable by external function sub.

One way to go about it might be to use Maple's CodeGeneration[Fortran] or CodeGeneration[C] in order to emit the source code for sub1. Then compile and link that into a .dll (or .so on unix or OSX). Then amend the define_external link flags so that it picks up this .dll and links additionally against it when setting up define_external('sub'....). See the ?COMPILE_OPTIONS help-page for how to amend the link flags. Also, the compilation of the sub1 source and creation of its .dll could be automated using ssystem calls in Maple. There's quite a bit of effort here, but done properly this should all work and be reasonably efficient, I think.

Another approach could be to use a so-called callback to sub1 a Maple procedure. The callback from sub to sub1 coule be done by passing that Maple procedure as part of the external call. See the ?WRAPPER help-page for information about such callbacks. You might even use the Maple Compiler:-Compile routine to compile the Maple procedure sub1, to make it fast. (I do not know how much overhead there might be in such a scheme, due to conversion of scalar arguments to and from hardware and software floats as they pass between these layers.)

acer

It is possible to view the procedures used in the elements.

> with(ScientificConstants):

> interface(verboseproc=3):

> GetElement(17,'density');

> GetElement(1,'electronaffinity');

The ones that I've looked at so far make some sense.

Querying the electron affinity of hydrogen reports that one should query the isotropic property of either the H[1] or H[2] isotope instead (otherwise the question doesn't make unique sense). Asking for the density of chlorine make sense only in the gas sense (but will that always be so?). Some queries have straightforward answers and the data is stored simply, without procedures. If one follows instructions then any numeric values (in an appropriate subcontext) can be extracted.

It looks to me like a justified difference rather than a problematic discrepancy. Of course, one can always fill out the software change request.

acer

You have obtained only an equation by entering,

      RET = 8.364128*10^(-4); 

That is not the same as performing an assignment to RET by entering,

      RET := 8.364128*10^(-4); 

Note the colon-equals (:=) instead of just equals (=).


acer

You have obtained only an equation by entering,

      RET = 8.364128*10^(-4); 

That is not the same as performing an assignment to RET by entering,

      RET := 8.364128*10^(-4); 

Note the colon-equals (:=) instead of just equals (=).


acer

It appears that PolynomialInterpolation doesn't like it when one mixes the types of the data arguments. In this case, you had d as a list and w as an Array. It works if they are made to be the same (either Vector, list, or 1x20 Array)

CurveFitting:-PolynomialInterpolation(Vector(d),Vector(w), x);

CurveFitting:-PolynomialInterpolation(Array(1..20,d),w, x);

CurveFitting:-PolynomialInterpolation(d,convert(w,list), x);

acer

It appears that PolynomialInterpolation doesn't like it when one mixes the types of the data arguments. In this case, you had d as a list and w as an Array. It works if they are made to be the same (either Vector, list, or 1x20 Array)

CurveFitting:-PolynomialInterpolation(Vector(d),Vector(w), x);

CurveFitting:-PolynomialInterpolation(Array(1..20,d),w, x);

CurveFitting:-PolynomialInterpolation(d,convert(w,list), x);

acer

First 486 487 488 489 490 491 492 Last Page 488 of 591