From: hreba <f_hreba@yahoo.com.br>
Subject: Re: How can one record component be local and another not?
Date: Wed, 6 May 2020 21:31:11 +0200
Date: 2020-05-06T21:31:11+02:00 [thread overview]
Message-ID: <hhghk0F702iU1@mid.individual.net> (raw)
In-Reply-To: <hhdrtkFk328U1@mid.individual.net>
On 5/5/20 9:08 PM, Niklas Holsti wrote:
>
> I don't understand -- System.Address is not an access type; why do you
> need to use an access type to produce this parameter? Do you need a
> pointer to the "params" component?
>
> Perhaps you can show a bit more of the actual code that has the problem?
>
Ok, I'll try to make it comprehensible without throwing a lot of code at
you.
I am writing a thick binding to the GSL library odeiv2 for numerically
integrating ODEs (ordinary differential equations). I already have the
thin binding gsl_odeiv2_h.ads. For initialization, I have to call the
following subprogram of the thin binding:
function gsl_odeiv2_driver_alloc_y_new
(sys : access constant gsl_odeiv2_system;
T : access constant gsl_odeiv2_step_type;
hstart : double;
epsabs : double;
epsrel : double) return access gsl_odeiv2_driver;
pragma Import (C, gsl_odeiv2_driver_alloc_y_new,
"gsl_odeiv2_driver_alloc_y_new");
Parameter sys defines the ODE; its type is
type gsl_odeiv2_system is record
c_function : access function
(arg1 : double;
arg2 : access double;
arg3 : access double;
arg4 : System.Address) return int;
jacobian : access function
(arg1 : double;
arg2 : access double;
arg3 : access double;
arg4 : access double;
arg5 : System.Address) return int;
dimension : aliased size_t;
params : System.Address;
end record;
pragma Convention (C_Pass_By_Copy, gsl_odeiv2_system);
Later, during integration, c_function() and jacobian() will be called
with parameters of type System.Address (arg4 and arg5 resp.). These
parameters must be passed as params inside sys to
gsl_odeiv2_driver_alloc_y_new().
Now to my own code (most of the thin binding was created automatically
with g++ -c -fdump-ada-spec-slim). Dglsys_P corresponds to c_function in
the thin binding, The package is essentially
generic
dim: Positive;
type Float is digits<>;
package odeiv2 is
err_noInit, -- Init_Solve() has not been called
err_Precision, -- precision of C.double used in GSL not sufficient
err_Method, -- integration method not implemented
err_SolveAgain: -- Solve_Again() call without former Solve()
Exception;
type Float_Array is array (1..dim) of Float;
type Float_Matrix is array (1..dim, 1..dim) of Float;
type Par_Array is array (Positive range <>) of Float;
type Method is (RK8PD);
type Solver is limited private;
type Dglsys_P is not null access procedure
(t: Float; -- independent variable
y: Float_Array; -- dependent variables at t
dydt: out Float_Array; -- 1. ordinary derivatives at t
params: Par_Array -- any parameters
);
-- omitted: type Jacobi_P is access procedure...
procedure Init_Solve
-- Init. a dglsys, must be called once before calling
-- (once or repeatedly) Solve() or Solve_Again().
-- The resulting sol must be an access type because of the internal
-- interface to the GSL library.
(Dglsys: Dglsys_P; -- the system of diff. equ.
Jacobi: Jacobi_P; -- the jacobi calc., if avail.
pars: access constant Par_Array; -- the parameters
met: Method; -- the solve method
h_start: Float; -- initial step size
epsabs: Float; -- absolute error tolerance
epsrel: Float; -- relative error tolerance
sol: aliased in out Solver
);
private
package C renames Interfaces.C;
package Ode renames gsl_odeiv2_h;
type C_Array is array (Integer range <>) of aliased C.double;
pragma Convention (C, C_Array);
type Parameters is record
dglpars: access constant Par_Array; -- pars of dglsys
Dglsys: Dglsys_P; -- dglsys calc.
Jacobi: Jacobi_P; -- Jacobi calc.
end record;
pragma Convention (C, Parameters);
type Parameters_Ptr is access all Parameters;
package Parameters_Conv is new
System.Address_To_Access_Conversions (Parameters);
type Solver is limited record
initialized: Boolean:= false; -- Init_Solve() has been called
firstcall_done: Boolean; -- first call done
store_y: Boolean; -- copy y to ya
ya: C_Array (1..dim); -- values of last Solve call
sys: aliased Ode.gsl_odeiv2_system;
driver: access Ode.gsl_odeiv2_driver;
all_pars: aliased Parameters;
all_pp: Parameters_Conv.Object_Pointer;
end record;
end odeiv2;
In the package body I have to define the c_function above (thin binding
spec.), which will call the corresponding function of type Dglsys_P
(thick binding), and it finds this in the parameters. then I define the
initialization subprogram.
package body odeiv2 is
package C_Arrays is new
Interfaces.C.Pointers (Integer, C.double, C_Array, 0.0);
function func (t: C.double; y,f: access C.double; params:
System.Address) return C.int;
pragma Convention (C, func);
function func (t: C.double; y,f: access C.double; params:
System.Address) return C.int
-- GSL version of Dglsys
is
use type System.Address;
all_pars: Parameters_Conv.Object_Pointer;
yf, dydt: Float_Array;
y0: C_Arrays.Pointer:= C_Arrays.Pointer(y);
f0: C_Arrays.Pointer:= C_Arrays.Pointer(f);
begin
all_pars:= Parameters_Conv.To_Pointer (params);
for i in 1..dim loop
yf(i):= Float(y0.all);
C_Arrays.Increment (y0);
end loop;
all_pars.Dglsys (Float(t), yf, dydt, all_pars.dglpars.all);
for i in 1..dim loop
f0.all:= C.double(dydt(i));
C_Arrays.Increment (f0);
end loop;
return gsl_errno_h.GSL_SUCCESS;
end func;
procedure Init_Solve
(Dglsys: Dglsys_P; -- the system of diff.equ.
Jacobi: Jacobi_P; -- jacobi calc., if available
pars: access constant Par_Array; -- the parameters
met: Method; -- the solve method
h_start: Float; -- initial step size
epsabs: Float; -- absolute error tolerance
epsrel: Float; -- relative error tolerance
sol: aliased in out Solver
)
is
gsl_met: access constant Ode.gsl_odeiv2_step_type;
begin
-- set all_pars
-- sol: flags for calling logic
sol.Initialized:= true;
sol.firstcall_done:= false;
sol.store_y:= true;
sol.all_pars.dglpars:= pars;
sol.all_pars.Dglsys:= Dglsys;
sol.all_pars.Jacobi:= Jacobi;
-- transform integration method to GSL format
case met is
when RK8PD => gsl_met:= Ode.gsl_odeiv2_step_rk8pd;
when others =>
raise err_Method
with "forgot to implement integration method";
end case;
-- build sys and driver
sol.all_pp:= sol.all_pars'Unchecked_Access;
sol.sys:=
(func'Access, jac'Access, C.size_t(dim),
Parameters_Conv.To_Address (sol.all_pp));
sol.driver:= Ode.gsl_odeiv2_driver_alloc_y_new
(sol.sys'Access, gsl_met,
C.double(h_start), C.double(epsabs), C.double(epsrel));
end Init_Solve;
-- %< -------------
end odeiv2;
The above version compiles. At first I didn't have the Solver component
all_pp, but passed app_pars'Address to the call of
gsl_odeiv2_driver_alloc_y_new at the end of Init_Solve. It too compiled.
But whatever I try, I don't get rid of the runtime error
raised CONSTRAINT_ERROR : odeiv2.ads:92:4 access check failed
It accuses the line
type Parameters is record
--
Frank Hrebabetzky, Kronach +49 / 9261 / 950 0565
next prev parent reply other threads:[~2020-05-06 19:31 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-05 11:04 How can one record component be local and another not? hreba
2020-05-05 11:33 ` AdaMagica
2020-05-05 11:38 ` AdaMagica
2020-05-05 12:59 ` hreba
2020-05-05 13:19 ` J-P. Rosen
2020-05-05 13:37 ` Jere
2020-05-05 14:28 ` hreba
2020-05-05 15:18 ` AdaMagica
2020-05-05 14:32 ` hreba
2020-05-05 11:43 ` AdaMagica
2020-05-05 12:55 ` hreba
2020-05-05 11:46 ` Simon Wright
2020-05-05 13:07 ` hreba
2020-05-05 17:00 ` Dmitry A. Kazakov
2020-05-05 11:48 ` Niklas Holsti
2020-05-05 13:44 ` hreba
2020-05-05 15:45 ` Jeffrey R. Carter
2020-05-05 17:17 ` hreba
2020-05-05 19:08 ` Niklas Holsti
2020-05-06 19:31 ` hreba [this message]
2020-05-09 19:43 ` Niklas Holsti
2020-05-10 15:10 ` hreba
2020-05-05 19:19 ` Jere
2020-05-06 6:42 ` Mark Lorenzen
2020-05-06 8:26 ` Simon Wright
2020-05-06 8:33 ` Mark Lorenzen
2020-05-05 17:32 ` hreba
2020-05-05 19:04 ` Niklas Holsti
2020-05-05 20:11 ` Niklas Holsti
2020-05-06 13:13 ` hreba
2020-05-06 17:30 ` Niklas Holsti
2020-05-06 18:28 ` Jere
2020-05-06 19:09 ` Niklas Holsti
2020-05-07 9:07 ` J-P. Rosen
2020-05-07 10:15 ` Niklas Holsti
2020-05-07 13:00 ` Egil H H
2020-05-07 13:25 ` Simon Wright
2020-05-07 10:31 ` Stefan.Lucks
2020-05-07 11:58 ` J-P. Rosen
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox