comp.lang.ada
 help / color / mirror / Atom feed
* C Interface example
@ 2007-02-03 15:20 artifact.one
  2007-02-03 16:15 ` Ludovic Brenta
                   ` (4 more replies)
  0 siblings, 5 replies; 30+ messages in thread
From: artifact.one @ 2007-02-03 15:20 UTC (permalink / raw)


Hi.

I'm having a bit of trouble getting my head around calling C code
in Ada. I'll spare you my failed attempts, basically I have this code:

(vector.h)

#ifndef VECTOR_H
#define VECTOR_H

float *vec_addNf(float *, float *, unsigned int);

#endif

(vec_add.c)

#include "vector.h"

float *vec_add(float *va, float *vb, unsigned int ne)
{
  unsigned int ind;
  for (ind = 0; ind < ne; ++ind)
    va[ind] += vb[ind];
  return va;
}

Now what would be the most simple and portable way to write
a vector,ads and vector.adb file? (Specification and body, in case
those are compiler-specific filenames, I'm not intimate with the
Ada language spec yet!). I just don't have a good enough
understanding of the language to see how it all fits together
yet and I usually learn by example.

MC




^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 15:20 C Interface example artifact.one
@ 2007-02-03 16:15 ` Ludovic Brenta
  2007-02-03 17:15   ` Simon Wright
  2007-02-03 17:39   ` artifact.one
  2007-02-03 16:19 ` Cesar Rabak
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 30+ messages in thread
From: Ludovic Brenta @ 2007-02-03 16:15 UTC (permalink / raw)


artifact.one writes:
> #ifndef VECTOR_H
> #define VECTOR_H
>
> float *vec_addNf(float *, float *, unsigned int);
>
> #endif

package Vec is
   type Array_Of_Floats is array (Natural range <>) of Float;
   function Add (VA     : access Array_Of_Floats;
                 VB     : in     Array_Of_Floats;
                 Length : in     Natural)
      return access Array_Of_Floats; -- Ada 2005 required here
   pragma Import (C, Add, "vec_addNf");
end Vec;

but all calls to Add will have to do something with the value
returned.  Looking at the body of vec_addNf, I see that the returned
value is useless, since the caller obviously already knows the address
of VA.  Taking advantage of that fact, we can instead declare a
procedure:

package Vec is
   type Array_Of_Floats is array (Natural range <>) of Float;
   procedure Add (VA     : in out Array_Of_Floats;
                  VB     : in     Array_Of_Floats;
                  Length : in     Natural);
   pragma Import (C, Add, "vec_addNf");
end Vec;

HTH

-- 
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 15:20 C Interface example artifact.one
  2007-02-03 16:15 ` Ludovic Brenta
@ 2007-02-03 16:19 ` Cesar Rabak
  2007-02-03 17:40   ` artifact.one
  2007-02-03 17:48 ` Gautier
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 30+ messages in thread
From: Cesar Rabak @ 2007-02-03 16:19 UTC (permalink / raw)


artifact.one@googlemail.com escreveu:
> Hi.
> 
> I'm having a bit of trouble getting my head around calling C code
> in Ada. I'll spare you my failed attempts, basically I have this code:
> 
[snipped]

What compiler(s) are using?




^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 16:15 ` Ludovic Brenta
@ 2007-02-03 17:15   ` Simon Wright
  2007-02-03 19:43     ` Ludovic Brenta
  2007-02-03 17:39   ` artifact.one
  1 sibling, 1 reply; 30+ messages in thread
From: Simon Wright @ 2007-02-03 17:15 UTC (permalink / raw)


Ludovic Brenta <ludovic@ludovic-brenta.org> writes:

>    type Array_Of_Floats is array (Natural range <>) of Float;

Is it unnecessary to say pragma Convention (C, Array_Of_Floats) here?



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 16:15 ` Ludovic Brenta
  2007-02-03 17:15   ` Simon Wright
@ 2007-02-03 17:39   ` artifact.one
  2007-02-04 14:34     ` Stephen Leake
  1 sibling, 1 reply; 30+ messages in thread
From: artifact.one @ 2007-02-03 17:39 UTC (permalink / raw)


On Feb 3, 4:15 pm, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote:
> artifact.one writes:
> > #ifndef VECTOR_H
> > #define VECTOR_H
>
> > float *vec_addNf(float *, float *, unsigned int);
>
> > #endif
>
> package Vec is
>    type Array_Of_Floats is array (Natural range <>) of Float;
>    function Add (VA     : access Array_Of_Floats;
>                  VB     : in     Array_Of_Floats;
>                  Length : in     Natural)
>       return access Array_Of_Floats; -- Ada 2005 required here
>    pragma Import (C, Add, "vec_addNf");
> end Vec;
>
> but all calls to Add will have to do something with the value
> returned.  Looking at the body of vec_addNf, I see that the returned
> value is useless, since the caller obviously already knows the address
> of VA.  Taking advantage of that fact, we can instead declare a
> procedure:

Yes, the original intent in C was to be able to do this sort of thing:

  vec_addNf(vec_addNf(va, vb), vec_addNf(vc, vd));

...which may or may not be possible or desirable in Ada.

>
> package Vec is
>    type Array_Of_Floats is array (Natural range <>) of Float;
>    procedure Add (VA     : in out Array_Of_Floats;
>                   VB     : in     Array_Of_Floats;
>                   Length : in     Natural);
>    pragma Import (C, Add, "vec_addNf");
> end Vec;
>
> HTH
>
> --
> Ludovic Brenta.

Thanks, that makes things a bit clearer. I'll go with the
procedure definition over the function.

Mc




^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 16:19 ` Cesar Rabak
@ 2007-02-03 17:40   ` artifact.one
  2007-02-03 19:59     ` Cesar Rabak
  0 siblings, 1 reply; 30+ messages in thread
From: artifact.one @ 2007-02-03 17:40 UTC (permalink / raw)


On Feb 3, 4:19 pm, Cesar Rabak <csra...@yahoo.com.br> wrote:
> artifact....@googlemail.com escreveu:> Hi.
>
> > I'm having a bit of trouble getting my head around calling C code
> > in Ada. I'll spare you my failed attempts, basically I have this code:
>
> [snipped]
>
> What compiler(s) are using?

GNAT.

MC




^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 15:20 C Interface example artifact.one
  2007-02-03 16:15 ` Ludovic Brenta
  2007-02-03 16:19 ` Cesar Rabak
@ 2007-02-03 17:48 ` Gautier
  2007-02-03 18:09   ` artifact.one
  2007-02-03 20:42   ` Pascal Obry
  2007-02-03 20:52 ` Jeffrey R. Carter
  2007-02-04 14:32 ` Stephen Leake
  4 siblings, 2 replies; 30+ messages in thread
From: Gautier @ 2007-02-03 17:48 UTC (permalink / raw)


artifact.one@googlemail.com:

> I'm having a bit of trouble getting my head around calling C code
> in Ada. I'll spare you my failed attempts, basically I have this code:
> 
> (vector.h)
> 
> #ifndef VECTOR_H
> #define VECTOR_H
> 
> float *vec_addNf(float *, float *, unsigned int);
> 
> #endif
> 
> (vec_add.c)
> 
> #include "vector.h"
> 
> float *vec_add(float *va, float *vb, unsigned int ne)
> {
>   unsigned int ind;
>   for (ind = 0; ind < ne; ++ind)
>     va[ind] += vb[ind];
>   return va;
> }
> 
> Now what would be the most simple and portable way to write
> a vector,ads and vector.adb file? (Specification and body, in case
> those are compiler-specific filenames, I'm not intimate with the
> Ada language spec yet!). I just don't have a good enough
> understanding of the language to see how it all fits together
> yet and I usually learn by example.

Looking at your code the most simple and portable way will be not to interface 
at all with C!

package Vectors is

   type Vector is array(Natural range <>) of Float;

   procedure Add(va: in out Vector; vb: in Vector);

end Vectors;

package body Vectors is

   procedure Add(va: in out Vector; vb: in Vector) is
   begin
     for i in va'Range loop
       va(i):= va(i) + vb(i);
     end loop;
   end Add;

end Vectors;

Note that most compilers accept the spec and the body (or more!) in the same 
file with the name of your choice; GNAT requires vectors.ads and vectors.adb
HTH
______________________________________________________________
Gautier         -- http://www.mysunrise.ch/users/gdm/index.htm
Ada programming -- http://www.mysunrise.ch/users/gdm/gsoft.htm

NB: For a direct answer, e-mail address on the Web site!



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 17:48 ` Gautier
@ 2007-02-03 18:09   ` artifact.one
  2007-02-03 19:17     ` Georg Bauhaus
                       ` (2 more replies)
  2007-02-03 20:42   ` Pascal Obry
  1 sibling, 3 replies; 30+ messages in thread
From: artifact.one @ 2007-02-03 18:09 UTC (permalink / raw)


On Feb 3, 5:48 pm, Gautier <gaut...@fakeaddress.nil> wrote:
> Looking at your code the most simple and portable way will be not to interface
> at all with C!
>
> package Vectors is
>
>    type Vector is array(Natural range <>) of Float;
>
>    procedure Add(va: in out Vector; vb: in Vector);
>
> end Vectors;
>
> package body Vectors is
>
>    procedure Add(va: in out Vector; vb: in Vector) is
>    begin
>      for i in va'Range loop
>        va(i):= va(i) + vb(i);
>      end loop;
>    end Add;
>
> end Vectors;
>
> Note that most compilers accept the spec and the body (or more!) in the same
> file with the name of your choice; GNAT requires vectors.ads and vectors.adb
> HTH

Hello.

Yes this was quite a contrived example because my real version of
vec_add()
actually calls Altivec, SSE, SSE2 or pure C code depending on detected
hardware,
which stretches on to about 300 lines. I didn't think anybody would
appreciate
reading all that just for an example on interfacing...

MC




^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 18:09   ` artifact.one
@ 2007-02-03 19:17     ` Georg Bauhaus
  2007-02-03 19:53       ` artifact.one
  2007-02-03 19:48     ` tmoran
  2007-02-04 14:37     ` Stephen Leake
  2 siblings, 1 reply; 30+ messages in thread
From: Georg Bauhaus @ 2007-02-03 19:17 UTC (permalink / raw)


On Sat, 2007-02-03 at 10:09 -0800, artifact.one@googlemail.com wrote:
> On Feb 3, 5:48 pm, Gautier <gaut...@fakeaddress.nil> wrote:
> > Looking at your code the most simple and portable way will be not to interface
> > at all with C!
> >
> > package Vectors is
> >
> >    type Vector is array(Natural range <>) of Float;
> >
> >    procedure Add(va: in out Vector; vb: in Vector);
> >
> > end Vectors;

In fact, Ada 2007 will provide this in the standard library,

with Ada.Numerics.Real_Arrays;

   va, vb, result: Real_Array(1 .. n);

   result := va + vb;

Not sure whether there is a big performance penalty
when not modifying va in place.


> Yes this was quite a contrived example because my real version of
> vec_add()
> actually calls Altivec, SSE, SSE2 or pure C code depending on detected
> hardware,
> which stretches on to about 300 lines.

Any reason to dismiss the BLAS libraries optimized for
the respective processors?





^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 17:15   ` Simon Wright
@ 2007-02-03 19:43     ` Ludovic Brenta
  0 siblings, 0 replies; 30+ messages in thread
From: Ludovic Brenta @ 2007-02-03 19:43 UTC (permalink / raw)


Simon Wright writes:
> Ludovic Brenta writes:
>
>>    type Array_Of_Floats is array (Natural range <>) of Float;
>
> Is it unnecessary to say pragma Convention (C, Array_Of_Floats) here?

After reading B.1(26) and B.1(13 .. 20), I think the answer is yes.
But in practice, with GNAT, this is probably unnecessary because of
B.1(20).

-- 
Ludovic Brenta.



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 18:09   ` artifact.one
  2007-02-03 19:17     ` Georg Bauhaus
@ 2007-02-03 19:48     ` tmoran
  2007-02-03 19:55       ` artifact.one
  2007-02-04 14:37     ` Stephen Leake
  2 siblings, 1 reply; 30+ messages in thread
From: tmoran @ 2007-02-03 19:48 UTC (permalink / raw)


> float *vec_addNf(float *, float *, unsigned int);
> Now what would be the most simple and portable way to write
> a vector,ads and vector.adb file? (Specification and body, in case

> reading all that just for an example on interfacing...

  If you want to call an existing C routine, not rewriting it in Ada,
then the literal translation of the calling interface is:

  type p_float is access all interfaces.c.c_float;

  function vec_addNf(va, vb : in p_float; n : in interfaces.c.unsigned)
  return p_float;
  pragma import(C, vec_addNf, "vec_addNf");
  -- Note: Do this if you really have a C calling convention.
  -- If you are running on MS Windows, you probably want "StdCall"
  -- instead of "C"

and then use it like this
  type vectors is array(interfaces.c.unsigned range <>)
    of aliased interfaces.c.c_float;
  va, vb : vectors(1 .. 100);
  trash : p_float;
  ...
  trash := vec_addNf(va(va'first)'unchecked_access,
                     vb(vb'first)'unchecked_access,
                     va'length);

If you were going to be doing a lot of complex calls on va, vb, vc, and vd
you might want instead

N : interfaces.c.unsigned := 123;
va_data, vb_data, vc_data, vd_data : vectors(1 .. N);
va : constant p_float := va_data(va_data'first)'unchecked_access;
vb : constant p_float := vb_data(vb_data'first)'unchecked_access;
vc : constant p_float := vc_data(vc_data'first)'unchecked_access;
vd : constant p_float := vd_data(vd_data'first)'unchecked_access;

so you could write things like

  trash := vec_addNf(vec_addNf(va,vb,N),vec_addNf(vc,vd,N), N);



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 19:17     ` Georg Bauhaus
@ 2007-02-03 19:53       ` artifact.one
  2007-02-03 20:02         ` Gautier
  0 siblings, 1 reply; 30+ messages in thread
From: artifact.one @ 2007-02-03 19:53 UTC (permalink / raw)


On Feb 3, 7:17 pm, Georg Bauhaus <bauh...@futureapps.de> wrote:
>
> Any reason to dismiss the BLAS libraries optimized for
> the respective processors?

What are they?

MC




^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 19:48     ` tmoran
@ 2007-02-03 19:55       ` artifact.one
  0 siblings, 0 replies; 30+ messages in thread
From: artifact.one @ 2007-02-03 19:55 UTC (permalink / raw)


On Feb 3, 7:48 pm, tmo...@acm.org wrote:
> > float *vec_addNf(float *, float *, unsigned int);
> > Now what would be the most simple and portable way to write
> > a vector,ads and vector.adb file? (Specification and body, in case
> > reading all that just for an example on interfacing...
>
>   If you want to call an existing C routine, not rewriting it in Ada,
> then the literal translation of the calling interface is:
>
>   type p_float is access all interfaces.c.c_float;
>
>   function vec_addNf(va, vb : in p_float; n : in interfaces.c.unsigned)
>   return p_float;
>   pragma import(C, vec_addNf, "vec_addNf");
>   -- Note: Do this if you really have a C calling convention.
>   -- If you are running on MS Windows, you probably want "StdCall"
>   -- instead of "C"
>
> and then use it like this
>   type vectors is array(interfaces.c.unsigned range <>)
>     of aliased interfaces.c.c_float;
>   va, vb : vectors(1 .. 100);
>   trash : p_float;
>   ...
>   trash := vec_addNf(va(va'first)'unchecked_access,
>                      vb(vb'first)'unchecked_access,
>                      va'length);
>
> If you were going to be doing a lot of complex calls on va, vb, vc, and vd
> you might want instead
>
> N : interfaces.c.unsigned := 123;
> va_data, vb_data, vc_data, vd_data : vectors(1 .. N);
> va : constant p_float := va_data(va_data'first)'unchecked_access;
> vb : constant p_float := vb_data(vb_data'first)'unchecked_access;
> vc : constant p_float := vc_data(vc_data'first)'unchecked_access;
> vd : constant p_float := vd_data(vd_data'first)'unchecked_access;
>
> so you could write things like
>
>   trash := vec_addNf(vec_addNf(va,vb,N),vec_addNf(vc,vd,N), N);

Thanks.

I will end up using some sort of preprocessor for all this stuff, but
I like to know how it works beforehand.

MC




^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 17:40   ` artifact.one
@ 2007-02-03 19:59     ` Cesar Rabak
  0 siblings, 0 replies; 30+ messages in thread
From: Cesar Rabak @ 2007-02-03 19:59 UTC (permalink / raw)


artifact.one@googlemail.com escreveu:
> On Feb 3, 4:19 pm, Cesar Rabak <csra...@yahoo.com.br> wrote:
>> artifact....@googlemail.com escreveu:> Hi.
>>
>>> I'm having a bit of trouble getting my head around calling C code
>>> in Ada. I'll spare you my failed attempts, basically I have this code:
>> [snipped]
>>
>> What compiler(s) are using?
> 
> GNAT.
> 
Get a look at the GNAT User Guide in the Section 2.10 "Mixed Language 
Programming", specially the item '2.10.1 Interfacing to C'

HTH

--
Cesar Rabak



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 19:53       ` artifact.one
@ 2007-02-03 20:02         ` Gautier
  2007-02-03 21:36           ` Georg Bauhaus
  0 siblings, 1 reply; 30+ messages in thread
From: Gautier @ 2007-02-03 20:02 UTC (permalink / raw)


>> Any reason to dismiss the BLAS libraries optimized for
>> the respective processors?
> 
> What are they?
> 
> MC

BLAS is "the" library for the things you would like to do.
Lucky you, you have even Ada bindings to it:

   http://topo.math.u-psud.fr/~sands/Programs/BLAS/index.html

______________________________________________________________
Gautier         -- http://www.mysunrise.ch/users/gdm/index.htm
Ada programming -- http://www.mysunrise.ch/users/gdm/gsoft.htm

NB: For a direct answer, e-mail address on the Web site!



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 17:48 ` Gautier
  2007-02-03 18:09   ` artifact.one
@ 2007-02-03 20:42   ` Pascal Obry
  1 sibling, 0 replies; 30+ messages in thread
From: Pascal Obry @ 2007-02-03 20:42 UTC (permalink / raw)
  To: Gautier

Gautier a �crit :
> Note that most compilers accept the spec and the body (or more!) in the
> same file with the name of your choice; GNAT requires vectors.ads and
> vectors.adb

That's not correct. '.ads' and '.adb' are only the default naming scheme.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 15:20 C Interface example artifact.one
                   ` (2 preceding siblings ...)
  2007-02-03 17:48 ` Gautier
@ 2007-02-03 20:52 ` Jeffrey R. Carter
  2007-02-03 20:57   ` artifact.one
                     ` (2 more replies)
  2007-02-04 14:32 ` Stephen Leake
  4 siblings, 3 replies; 30+ messages in thread
From: Jeffrey R. Carter @ 2007-02-03 20:52 UTC (permalink / raw)


artifact.one@googlemail.com wrote:
> float *vec_add(float *va, float *vb, unsigned int ne)
> {
>   unsigned int ind;
>   for (ind = 0; ind < ne; ++ind)
>     va[ind] += vb[ind];
>   return va;
> }
> 
> Now what would be the most simple and portable way to write
> a vector,ads and vector.adb file? (Specification and body, in case
> those are compiler-specific filenames, I'm not intimate with the
> Ada language spec yet!). I just don't have a good enough
> understanding of the language to see how it all fits together
> yet and I usually learn by example.

I think all of the examples posted so far have some minor problem or 
other in meeting your goal of portability. I'd suggest

with Interfaces.C;
package C_Vectors is
    type Vector is array (Positive range <>) of Interfaces.C.C_Float;
    pragma Convention (C, Vector);

    procedure Add
       (To : in out Vector; Using : in Vector; Length : in Natural);
end C_Vectors;

package body C_Vectors is
    procedure Add
       (To : in out Vector; Using : in Vector; Length : in Natural)
    is
       type C_Ptr is access all Interfaces.C.C_Float;
       pragma Convention (C, C_Ptr);

       function C_Add
          (To : Vector; Using : Vector: Length : Interfaces.C.Unsigned)
       return C_Ptr;
       pragma Import (C, C_Add, "vec_addNf");

       Result : C_Ptr;
    begin -- Add
       Result := C_Add (To, Using, Interfaces.C.Unsigned (Length) );
    end Add;
end C_Vectors;

-- 
Jeff Carter
"C++ is like jamming a helicopter inside a Miata
and expecting some sort of improvement."
Drew Olbrich
51



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 20:52 ` Jeffrey R. Carter
@ 2007-02-03 20:57   ` artifact.one
  2007-02-04  4:05     ` Jeffrey R. Carter
  2007-02-04 11:52   ` Simon Wright
  2007-02-05  8:56   ` Maciej Sobczak
  2 siblings, 1 reply; 30+ messages in thread
From: artifact.one @ 2007-02-03 20:57 UTC (permalink / raw)


On Feb 3, 8:52 pm, "Jeffrey R. Carter" <jrcar...@acm.org> wrote:
> artifact....@googlemail.com wrote:
> > float *vec_add(float *va, float *vb, unsigned int ne)
> > {
> >   unsigned int ind;
> >   for (ind = 0; ind < ne; ++ind)
> >     va[ind] += vb[ind];
> >   return va;
> > }
>
> > Now what would be the most simple and portable way to write
> > a vector,ads and vector.adb file? (Specification and body, in case
> > those are compiler-specific filenames, I'm not intimate with the
> > Ada language spec yet!). I just don't have a good enough
> > understanding of the language to see how it all fits together
> > yet and I usually learn by example.
>
> I think all of the examples posted so far have some minor problem or
> other in meeting your goal of portability. I'd suggest
>
> with Interfaces.C;
> package C_Vectors is
>     type Vector is array (Positive range <>) of Interfaces.C.C_Float;
>     pragma Convention (C, Vector);
>
>     procedure Add
>        (To : in out Vector; Using : in Vector; Length : in Natural);
> end C_Vectors;
>
> package body C_Vectors is
>     procedure Add
>        (To : in out Vector; Using : in Vector; Length : in Natural)
>     is
>        type C_Ptr is access all Interfaces.C.C_Float;
>        pragma Convention (C, C_Ptr);
>
>        function C_Add
>           (To : Vector; Using : Vector: Length : Interfaces.C.Unsigned)
>        return C_Ptr;
>        pragma Import (C, C_Add, "vec_addNf");
>
>        Result : C_Ptr;
>     begin -- Add
>        Result := C_Add (To, Using, Interfaces.C.Unsigned (Length) );
>     end Add;
> end C_Vectors;
>

Hi.

This is compiler-agnostic, yes?

thanks,
MC




^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 20:02         ` Gautier
@ 2007-02-03 21:36           ` Georg Bauhaus
  0 siblings, 0 replies; 30+ messages in thread
From: Georg Bauhaus @ 2007-02-03 21:36 UTC (permalink / raw)


On Sat, 2007-02-03 at 21:02 +0100, Gautier wrote:
> >> Any reason to dismiss the BLAS libraries optimized for
> >> the respective processors?
> > 
> > What are they?
> > 
> > MC
> 
> BLAS is "the" library for the things you would like to do.
> Lucky you, you have even Ada bindings to it:
> 
>    http://topo.math.u-psud.fr/~sands/Programs/BLAS/index.html
> 

And also
http://math-atlas.sourceforge.net/faq.html





^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 20:57   ` artifact.one
@ 2007-02-04  4:05     ` Jeffrey R. Carter
  0 siblings, 0 replies; 30+ messages in thread
From: Jeffrey R. Carter @ 2007-02-04  4:05 UTC (permalink / raw)


artifact.one@googlemail.com wrote:
> On Feb 3, 8:52 pm, "Jeffrey R. Carter" <jrcar...@acm.org> wrote:
>>
>> with Interfaces.C;
>> package C_Vectors is
>>     type Vector is array (Positive range <>) of Interfaces.C.C_Float;
>>     pragma Convention (C, Vector);
>>
>>     procedure Add
>>        (To : in out Vector; Using : in Vector; Length : in Natural);
>> end C_Vectors;
>>
>> package body C_Vectors is
>>     procedure Add
>>        (To : in out Vector; Using : in Vector; Length : in Natural)
>>     is
>>        type C_Ptr is access all Interfaces.C.C_Float;
>>        pragma Convention (C, C_Ptr);
>>
>>        function C_Add
>>           (To : Vector; Using : Vector: Length : Interfaces.C.Unsigned)
>>        return C_Ptr;
>>        pragma Import (C, C_Add, "vec_addNf");
>>
>>        Result : C_Ptr;
>>     begin -- Add
>>        Result := C_Add (To, Using, Interfaces.C.Unsigned (Length) );
>>     end Add;
>> end C_Vectors;
>>
> 
> This is compiler-agnostic, yes?

Should be. Everything that interacts with C is either from Interfaces.C 
or declared Convention C, so you're not relying on a compiler using the 
same representation as C types, even though that's usually the case. The 
C function returns a pointer, so this imports it that way, and provides 
a place for the returned value (which it ignores). C allows you to call 
a function as a procedure (in Ada terms), but Ada doesn't, and you can't 
be sure what will happen if you call a C function as a procedure from Ada.

Now that I look at it, you can leave the Length parameter off Add, and 
pass To'Length to C_Add:

procedure Add (To : in out Vector; Using : Vector);

Result := C_Add (To, Using, To'Length);

No conversion to Unsigned is needed, because 'Length is 
Universal_Integer, and implicitly converted as needed. Of course, you 
have to be sure To'Length = Using'Length (or you could put this check in 
Add), just as in C.

Also, you might get a warning that you never modify To, depending on 
your compiler. To will be passed to C_Add as a float*, so C_Add can 
modify it, but Ada doesn't know that C_Add modifies it.

-- 
Jeff Carter
"C++ is like jamming a helicopter inside a Miata
and expecting some sort of improvement."
Drew Olbrich
51



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 20:52 ` Jeffrey R. Carter
  2007-02-03 20:57   ` artifact.one
@ 2007-02-04 11:52   ` Simon Wright
  2007-02-04 20:59     ` Jeffrey R. Carter
  2007-02-05  8:56   ` Maciej Sobczak
  2 siblings, 1 reply; 30+ messages in thread
From: Simon Wright @ 2007-02-04 11:52 UTC (permalink / raw)


"Jeffrey R. Carter" <jrcarter@acm.org> writes:

>    procedure Add
>       (To : in out Vector; Using : in Vector; Length : in Natural)
>    is

In your later post you note that Ada can work out the length without
needing it as a parameter here. However, in either case I would put in
a check that To'Length is equal to Using'Length (and to Length, if
supplied).

I would probably raise Constraint_Error here (can't use pragma Assert
in '95 and be portable).



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 15:20 C Interface example artifact.one
                   ` (3 preceding siblings ...)
  2007-02-03 20:52 ` Jeffrey R. Carter
@ 2007-02-04 14:32 ` Stephen Leake
  4 siblings, 0 replies; 30+ messages in thread
From: Stephen Leake @ 2007-02-04 14:32 UTC (permalink / raw)


artifact.one@googlemail.com writes:

> (vector.h)
>
> #ifndef VECTOR_H
> #define VECTOR_H
>
> float *vec_addNf(float *, float *, unsigned int);
>
> #endif
>
> (vec_add.c)
>
> #include "vector.h"
>
> float *vec_add(float *va, float *vb, unsigned int ne)
> {
>   unsigned int ind;
>   for (ind = 0; ind < ne; ++ind)
>     va[ind] += vb[ind];
>   return va;
> }
>
> Now what would be the most simple and portable way to write
> a vector,ads and vector.adb file? 

Drop the C code entirely, and use SAL;
http://stephe-leake.org/ada/sal.html

That way, you get array length checks, and appropriate exceptions,
rather than status, for singularities.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 17:39   ` artifact.one
@ 2007-02-04 14:34     ` Stephen Leake
  0 siblings, 0 replies; 30+ messages in thread
From: Stephen Leake @ 2007-02-04 14:34 UTC (permalink / raw)


artifact.one@googlemail.com writes:

> Yes, the original intent in C was to be able to do this sort of thing:
>
>   vec_addNf(vec_addNf(va, vb), vec_addNf(vc, vd));
>
> ...which may or may not be possible or desirable in Ada.

In Ada, this should be:

va := va + vb + vc + vd;

Note that I'm not sure va was the intended result, from the C code.
But I'm _very_ sure what the intended result is from the Ada code.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 18:09   ` artifact.one
  2007-02-03 19:17     ` Georg Bauhaus
  2007-02-03 19:48     ` tmoran
@ 2007-02-04 14:37     ` Stephen Leake
  2 siblings, 0 replies; 30+ messages in thread
From: Stephen Leake @ 2007-02-04 14:37 UTC (permalink / raw)


artifact.one@googlemail.com writes:

> Yes this was quite a contrived example because my real version of
> vec_add() actually calls Altivec, SSE, SSE2 or pure C code depending
> on detected hardware, which stretches on to about 300 lines. 

Ok. It does make sense to interface that to Ada, rather than just
throwing it out.

> I didn't think anybody would appreciate reading all that just for an
> example on interfacing...

True, but it would have helped to say "The real code does ..., so I
don't want to rewrite it in Ada".

You should still strive to make the Ada code use operators, and
constrained arrays whenever possible.

-- 
-- Stephe



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-04 11:52   ` Simon Wright
@ 2007-02-04 20:59     ` Jeffrey R. Carter
  0 siblings, 0 replies; 30+ messages in thread
From: Jeffrey R. Carter @ 2007-02-04 20:59 UTC (permalink / raw)


Simon Wright wrote:
> 
> In your later post you note that Ada can work out the length without
> needing it as a parameter here. However, in either case I would put in
> a check that To'Length is equal to Using'Length (and to Length, if
> supplied).

Right. I mentioned that. Length should never be needed; you can always 
pass slices.

-- 
Jeff Carter
"Now go away or I shall taunt you a second time."
Monty Python & the Holy Grail
07



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-03 20:52 ` Jeffrey R. Carter
  2007-02-03 20:57   ` artifact.one
  2007-02-04 11:52   ` Simon Wright
@ 2007-02-05  8:56   ` Maciej Sobczak
  2007-02-05 18:12     ` Jeffrey R. Carter
  2 siblings, 1 reply; 30+ messages in thread
From: Maciej Sobczak @ 2007-02-05  8:56 UTC (permalink / raw)


Jeffrey R. Carter wrote:

> I think all of the examples posted so far have some minor problem or 
> other in meeting your goal of portability. I'd suggest

>    begin -- Add
>       Result := C_Add (To, Using, Interfaces.C.Unsigned (Length) );
>    end Add;

What about assigning something to Result and not using Result?
That doesn't get through with some pedantic warning switches.

-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-05  8:56   ` Maciej Sobczak
@ 2007-02-05 18:12     ` Jeffrey R. Carter
  2007-02-06  1:48       ` Randy Brukardt
  0 siblings, 1 reply; 30+ messages in thread
From: Jeffrey R. Carter @ 2007-02-05 18:12 UTC (permalink / raw)


Maciej Sobczak wrote:
> 
> What about assigning something to Result and not using Result?
> That doesn't get through with some pedantic warning switches.

True, you may get a warning, just as you may about not changing To. But 
it's perfectly legal, portable Ada.

-- 
Jeff Carter
"Spam! Spam! Spam! Spam! Spam! Spam! Spam! Spam!"
Monty Python's Flying Circus
53



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-05 18:12     ` Jeffrey R. Carter
@ 2007-02-06  1:48       ` Randy Brukardt
  2007-02-06  8:20         ` Maciej Sobczak
  2007-02-06 19:18         ` Jeffrey R. Carter
  0 siblings, 2 replies; 30+ messages in thread
From: Randy Brukardt @ 2007-02-06  1:48 UTC (permalink / raw)


"Jeffrey R. Carter" <jrcarter@acm.org> wrote in message
news:BsKxh.1174338$084.631125@attbi_s22...
> Maciej Sobczak wrote:
> >
> > What about assigning something to Result and not using Result?
> > That doesn't get through with some pedantic warning switches.
>
> True, you may get a warning, just as you may about not changing To. But
> it's perfectly legal, portable Ada.

Well, it's legal, and it is portable in this case, but it is a bad habit to
get into. (That's why the pedantic warning.) 11.6(5) allows the removal of
code that raises exceptions if the result is not used. I don't think it
applies to external code like C, but it certainly does apply to Ada code.
(And, like all points about 11.6, it's likely to result in a roaring
argument; no one is quite sure what is and is not allowed.)

Anyway, the point is that if you just drop the result on the floor, the Ada
compiler might be allowed to omit the call, too. So it is always best to use
the result somehow. In this case, test it for null and do something
explicit:

    if Result = null then
        raise Internal_Error;
    end if;

where Internal_Error is an appropriately defined exception.

                           Randy.





^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-06  1:48       ` Randy Brukardt
@ 2007-02-06  8:20         ` Maciej Sobczak
  2007-02-06 19:18         ` Jeffrey R. Carter
  1 sibling, 0 replies; 30+ messages in thread
From: Maciej Sobczak @ 2007-02-06  8:20 UTC (permalink / raw)


Randy Brukardt wrote:

> Anyway, the point is that if you just drop the result on the floor, the Ada
> compiler might be allowed to omit the call, too. So it is always best to use
> the result somehow. In this case, test it for null and do something
> explicit:
> 
>     if Result = null then
>         raise Internal_Error;
>     end if;
> 
> where Internal_Error is an appropriately defined exception.

What about:

pragma Assert(Result /= null);

It's shorter, looks more "serious" and uses optimistic positive logic 
instead of a negative one ("I'm alive!" instead of "Let's check whether 
I'm dead").

The only problem is that there is no choice of exception.

-- 
Maciej Sobczak : http://www.msobczak.com/
Programming    : http://www.msobczak.com/prog/



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: C Interface example
  2007-02-06  1:48       ` Randy Brukardt
  2007-02-06  8:20         ` Maciej Sobczak
@ 2007-02-06 19:18         ` Jeffrey R. Carter
  1 sibling, 0 replies; 30+ messages in thread
From: Jeffrey R. Carter @ 2007-02-06 19:18 UTC (permalink / raw)


Randy Brukardt wrote:
> 
> Anyway, the point is that if you just drop the result on the floor, the Ada
> compiler might be allowed to omit the call, too. So it is always best to use
> the result somehow. In this case, test it for null and do something
> explicit:

OK. You're probably right, but I thought the compiler had to be able to 
determine that there are no side effects from the call to do this, and 
could never determine that for an imported subprogram.

-- 
Jeff Carter
"Pray that there's intelligent life somewhere up in
space, 'cause there's bugger all down here on earth."
Monty Python's Meaning of Life
61



^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2007-02-06 19:18 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-03 15:20 C Interface example artifact.one
2007-02-03 16:15 ` Ludovic Brenta
2007-02-03 17:15   ` Simon Wright
2007-02-03 19:43     ` Ludovic Brenta
2007-02-03 17:39   ` artifact.one
2007-02-04 14:34     ` Stephen Leake
2007-02-03 16:19 ` Cesar Rabak
2007-02-03 17:40   ` artifact.one
2007-02-03 19:59     ` Cesar Rabak
2007-02-03 17:48 ` Gautier
2007-02-03 18:09   ` artifact.one
2007-02-03 19:17     ` Georg Bauhaus
2007-02-03 19:53       ` artifact.one
2007-02-03 20:02         ` Gautier
2007-02-03 21:36           ` Georg Bauhaus
2007-02-03 19:48     ` tmoran
2007-02-03 19:55       ` artifact.one
2007-02-04 14:37     ` Stephen Leake
2007-02-03 20:42   ` Pascal Obry
2007-02-03 20:52 ` Jeffrey R. Carter
2007-02-03 20:57   ` artifact.one
2007-02-04  4:05     ` Jeffrey R. Carter
2007-02-04 11:52   ` Simon Wright
2007-02-04 20:59     ` Jeffrey R. Carter
2007-02-05  8:56   ` Maciej Sobczak
2007-02-05 18:12     ` Jeffrey R. Carter
2007-02-06  1:48       ` Randy Brukardt
2007-02-06  8:20         ` Maciej Sobczak
2007-02-06 19:18         ` Jeffrey R. Carter
2007-02-04 14:32 ` Stephen Leake

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox