The future of PolyORB and the DSA

Hi,

I am trying to get my application up and running on a cluster of Linux boxes (data acquisition at rate of ~480MB/s, and DSP).

In the past (around 2003/4) I have developed a system using the DSA with the GNAT Pro compiler, and the software performed very well.

For my current application I got the PolyORB source code from the github, configured it as:

./configure --with-appli-perso=“DSA CORBA MOMA” ,
and build it successfully.

I have a problem with building the dsa echo example from /PolyORB/examples/dsa/echo.

The command :

po_gnatdist echo.cfg

Produces:

/usr/bin/gnat list polyorb.ali -Ppolyorb -s -aP/usr/local/lib/gnat
/usr/bin/gprbuild echo_monolithic_app.adb -c -P /home/darek/opt/PolyORB/examples/dsa/echo/dsa/x86_64-unknown-linux-gnu/echo_dist_app.gpr -margs -aP/usr/local/lib/gnat
Compile
[Ada] echo_monolithic_app.adb
/usr/bin/gnat list echo_monolithic_app.ali -V -P /home/darek/opt/PolyORB/examples/dsa/echo/dsa/x86_64-unknown-linux-gnu/echo_dist_app.gpr -aP/usr/local/lib/gnat
/usr/bin/gnat list a-sttebu.ali client.ali polyorb.ali polyorb-dsa_p.ali polyorb-dsa_p-partitions.ali server.ali -V -P /home/darek/opt/PolyORB/examples/dsa/echo/dsa/x86_64-unknown-linux-gnu/echo_dist_app.gpr -aP/usr/local/lib/gnat
Can’t find source for a-sttebu.ali
/usr/bin/gnat compile /usr/lib/gcc/x86_64-linux-gnu/12/adainclude/a-sttebu.adb -gnatc -P /home/darek/opt/PolyORB/examples/dsa/echo/dsa/x86_64-unknown-linux-gnu/echo_dist_app.gpr -margs -aP/usr/local/lib/gnat
gprbuild: “/usr/lib/gcc/x86_64-linux-gnu/12/adainclude/a-sttebu.adb” was not found in the sources of any project
/usr/bin/gnat list a-sttebu.ali -V -P /home/darek/opt/PolyORB/examples/dsa/echo/dsa/x86_64-unknown-linux-gnu/echo_dist_app.gpr -aP/usr/local/lib/gnat
Can’t find source for a-sttebu.ali
po_gnatdist: failed to load ALI for /usr/lib/gcc/x86_64-linux-gnu/12/adainclude/a-sttebu.adb
po_gnatdist: *** can’t continue

These files exist (a-sttebu*.ali, a-sttebu.adb, a-*sttebu.ads) in their locations but the system somehow does not recognize them.

Any idea how to solve it?

The statement from the PolyORB documentation says:

”PolyORB is a deprecated product. It will be baselined with the GNAT Pro release 28. After this release, there will be no new versions of this product. Contact AdaCore support to get recommendations for replacements.”

Does it mean that also the DSA would have the same longevity problem?

Thanks for your help.

Regards,

Darek

P.S. This the SW configuration I am using for this experiment:

  • System: Linux 6.1.0-41-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.158-1 (2025-11-09) x86_64 GNU/Linux
  • Compiler : gcc version 12.2.0 (Debian 12.2.0-14+deb12u1)
  • PolyORB Release 20.0w
1 Like

Some earlier discussion about this, in case you haven’t seen it:

Also,

The first step would be to look at the project structure and the gpr files.
You haven’t provided any links.
Please don’t expect people to conjure a solution if you’re not willing to give critical details.

That potentially sounds like an environment variable issue. Like some kind of path variable is not set to point to them.

As always with Unix-like systems: first check permissions and ownership.
If that isn’t it, check the path.
Third, check the parameters; often with using other-people’s GNAT projects, there’s a parameter that you need to set. (IIRC, the most frequent offender is include-directory, --I, IIRC; the penultimate-most offender is the linking-include.)
Fourth, check the library-level includes; it’s more rare, but frustrating when the GPR’s with-dependency is dropped.
Fifth, if you made it this far, it’s time to start backtracking and seeing if the compile and installations are good.

Try to use toolchain from Alire. Use of other compilers, especially provided by some Linux-es results in mysterious issue.

Hi @darek,

Welcome to the forum. It’s great to hear from another Polyorb DSA user!

I encountered this problem several years ago and reported it to the Polyorb github Issues page. I provided a rather nasty ‘workaround’ which I’ve been using until late last year, when I realised that PO was at end of life. So late last year, I looked into the po_gnatdist code itself.

After several weeks (yes, I’m that slow) of debugging, I found the cause of the problem. ‘Ada.Strings.Text_Buffers’ (a-sttebu.ads), a new Ada2022 package which supports user overriding of the ‘Image attribute, is implicitly ‘with’ed by one or more packages in the Ada runtime. At least one such package is ‘Ada.Text_IO’. I emphasise ‘implicitly’, since it is different to ‘indirectly’.

A section of po_gnatdist code uses ‘gnat list’ to build a list of application dependencies. Unfortunately, ‘gnat list’ was including ‘a-sttebu.ads’ in this list, which resulted in the error. My ‘fix’ was to add an ‘if’ guard against Ada runtime files being included in the creation of the application dependency list.

The patch can be found here … patch.

Regards.

5 Likes

Hi,

Not sure, if I got your suggestion right. I tried to build an example that is included in PolyORB distribution, and compilation process failed. What else shall I can provide in this case?

Regards,

Darek

Did you apply the patch and rebuild/reinstall polyorb ?

Hi @charlie5 ,

Thank you very much for your answer and the fix. I apply your solution, and re-build/install the PolyORB system. This time, I just created only the DSA personality:

./configure --with-appli-perso=“DSA”

After that, I tried to build the echo example from ~/PolyORB/examples/dsa/echo directory. The ‘po_gnatdist echo.cfg’ command worked well, and it generated the (working) binaries.

I also tried to build the demo example (PolyORB/examples/dsa/demo) by executing the following command:

po_gnatdist testbed.cfg

In this case, the process failed with the error:

usr/bin/gnat list polyorb.ali -Ppolyorb -s -aP/usr/local/lib/gnat
/usr/bin/gprbuild testbed_monolithic_app.adb -c -P /home/darek/opt/PolyORB/examples/dsa/demo/dsa/x86_64-unknown-linux-gnu/testbed_dist_app.gpr -margs -aP/usr/local/lib/gnat
Compile
[Ada] testbed_monolithic_app.adb
[Ada] rt.ads
cannot generate code for file rt.ads (package spec)
gprbuild: *** compilation phase failed

Not sure what to think about it.

Now, let’s hit another problem :slight_smile: !

In my experiments/proof of concept with the DSA , I would like to:

  • use 3 machines.
  • use 1 machine as a master, and 2 machines as computation nodes (if it works, the computation nodes would also perform data acquisition - one task for computations, one task for data acquisition, data exchange via a protected object).
  • create and run computation tasks on these two computers.

So, the configuration file for DSA is like this:

File poly_dsa.cfg

configuration poly_dsa is

pragma starter(ada);

node_00 :partition := (run_dsa);
node_01 :partition := (calc_node_01);
node_02 :partition := (calc_node_02);

for node_00’directory use “/tmp/bin/”;
for node_01’directory use “/tmp/bin/”;
for node_02’directory use “/tmp/bin/”;

for node_00’host use “192.168.100.15”;
for node_01’host use “192.168.100.16”;
for node_02’host use “192.168.100.17”;

for node_01’self_location use (“tcp”,“192.168.100.16”);
for node_01’reconnection use fail_until_restart;

for node_02’self_location use (“tcp”,“192.168.100.17”);
for node_02’reconnection use fail_until_restart;

channel_0_1 : channel := (node_00, node_01);
channel_0_2 : channel := (node_00, node_02);

procedure run_dsa is in node_00;

end poly_dsa;

and the code is:


File Calc_Node_01.ads

private with System.Multiprocessors;

package Calc_Node_01 is
   
   pragma Remote_Call_Interface;
    

   
   type tComputation_Task_Acc is private;
  
   
   procedure Create_Computation_Task(Comp_Task : in out tComputation_Task_Acc; CPU_Num : Positive; Ok :  out Boolean);  
   
   procedure Free_Computation_Task(Comp_Task : in out tComputation_Task_Acc);
   
   procedure Start_Task(Comp_Task : in out tComputation_Task_Acc;
                        Node_Number : Positive);
   
   procedure Stop_Task(Comp_Task : in out tComputation_Task_Acc);
      
private
   
   package MCU renames System.Multiprocessors;
   
    task  type tComputation_Task (Cpu_Num : MCU.CPU)  with Storage_Size => 10 * 1024 * 1024 *1024, CPU => Cpu_Num  is 
      entry Init(Node_Number : Positive); 
      entry Start_Computations;   
      entry Stop_Computations;
   end tComputation_Task;

   
   
   type tComputation_Task_Acc is access all  tComputation_Task;
   
end Calc_Node_01;


File Calc_Node_01.adb

with Ada.Text_IO;
with Ada.Unchecked_Deallocation;
with Ada.Task_Identification;



package body Calc_Node_01 is
 
   
   package TIO renames Ada.Text_IO;
   
   
   
     task body tComputation_Task is     
     L_Node_Number: Positive;
     Stop_Task : Boolean := False;
     
   
      type tArray_3D is array(1..1000, 1..1000, 1..1000) of Float;
      
      Arr  : tArray_3D := (others => (others => (others => 1.0)));
      Res  : Float := 0.0;
   begin      
      accept Init (Node_Number : Positive) do
         L_Node_Number := Node_Number;        
      end Init;                          
      
      accept Start_Computations;
      loop
         select
            accept Stop_Computations  do
              Stop_Task := True;      
            end Stop_Computations;
         else                                    
            exit when Stop_Task;
            
            for i in Arr'Range(1) loop               
               for j in Arr'Range(2) loop
                  for k in Arr'Range(3) loop
                     Res := Res + Res * Arr(i, j, k) ;
                  end loop;                  
               end loop;               
            end loop;
            TIO.Put(".");              
            
         end select;
      end loop;
      
   end tComputation_Task;
   
   --|--------------------------------------------------------------------------
   
    
   procedure Create_Computation_Task(Comp_Task : in out tComputation_Task_Acc; CPU_Num : Positive; Ok :  out Boolean) is
      Exec_Unit_Id_Str : constant String :="[Create_Computation_Task] ";      
      LCPU_Num : MCU.CPU;
   begin 
      if CPU_Num'Valid  then 
         LCPU_Num := MCU.CPU(CPU_Num);
      end if;
      
      Comp_Task  := new tComputation_Task(LCPU_Num);
      Ok := Comp_Task /= null; 
      if  Ok then 
         TIO.Put_Line(Exec_Unit_Id_Str & "Creation of the task has been sucesfully completed.");           
      else
         TIO.Put_Line(Exec_Unit_Id_Str & "Creation of the  task has failed.");
      end if;        
   end Create_Computation_Task;
   
   
   --|-------------------------------------------------------------------------------
   
   procedure  Free_Computation_Task(Comp_Task : in out tComputation_Task_Acc) is
      procedure  Free is new  Ada.Unchecked_Deallocation (tComputation_Task, tComputation_Task_Acc);
   begin 
      if Comp_Task  /= null  and then not Ada.Task_Identification.Is_Terminated (Comp_Task'Identity) then                                                                                               
         Free(Comp_Task);                     
      end if;                  
   end Free_Computation_Task;
   
   --|--------------------------------------------------------------------------
   
   procedure Start_Task(Comp_Task : in out tComputation_Task_Acc; Node_Number : Positive) is
   
   begin 
      Comp_Task.all.Init (Node_Number => Node_Number);
      Comp_Task.all.Start_Computations;
   end Start_Task;
   
   
   
   --|--------------------------------------------------------------------------
   
   procedure Stop_Task(Comp_Task : in out tComputation_Task_Acc) is
   begin
      Comp_Task.all.Stop_Computations;
      
   end Stop_Task;
   
   --|--------------------------------------------------------------------------
    
   

The code for Calc_Node_02 differs only in the package name (Calc_Node_02 instead of Calc_Node_01).

The main file is Run_Dsa.adb

with System.Multiprocessors;
with System.Multiprocessors.Dispatching_Domains;



pragma Elaborate_All(Calc_Node_01);
pragma Elaborate_All(Calc_Node_02);


procedure Run_Dsa is



   package TIO renames   Ada.Text_IO;
   package CN_01 renames Calc_Node_01;
   package CN_02 renames Calc_Node_02;

   package MPU  renames  System.Multiprocessors;

   N_01 : CN_01.tComputation_Task_Acc;
   N_02 : CN_02.tComputation_Task_Acc;
   Ok   : Boolean;

begin
   TIO.Put_Line("This machine has " & MPU.Number_Of_CPUs'Image & " cores.");
   TIO.Put_Line("Start DS...");
   
   CN_01.Create_Computation_Task (Comp_Task =>  N_01, Cpu_Num => 6, Ok => Ok);
   if not Ok then
      return;
   end if;

   CN_02.Create_Computation_Task (Comp_Task =>  N_02, Cpu_Num => 5, Ok => Ok);
   if not Ok then
      return;
   end if;

   CN_01.Start_Task (Comp_Task =>  N_01, Node_Number => 1 );
   CN_02.Start_Task (Comp_Task =>  N_02, Node_Number => 2 );

   delay(10.0);
   CN_01.Stop_Task (Comp_Task =>  N_01);
   CN_02.Stop_Task (Comp_Task =>  N_02);

   TIO.Put_Line("Freeing the tasks ...");
   CN_01.Free_Computation_Task(Comp_Task => N_01);
   CN_02.Free_Computation_Task(Comp_Task => N_02);

   TIO.Put_Line("DSA completed");

end Run_Dsa;

and the project file is:

project Poly_Dsa is

   for Source_Dirs use ("ada_src");
   for Object_Dir use "obj";
   for Main use ("run_dsa.adb");
   for Exec_Dir use "bin";

   
end Poly_Dsa;

It compiles and works as a regular Linux application running on a single PC.

Now, the fun part. Executing command :

po_gnatdist poly_dsa.cfg

compilers everything as it should but is some mysterious way the linking process failed throwing the following messages:


Bind
[gprbind] partition.bexch
[Ada] partition.ali
Link
[link] partition.adb
/usr/bin/ld: /home/darek/work/dsa_dev/ada_src/dsa/x86_64-unknown-linux-gnu/stubs/calc_node_02.o: warning: relocation against calc_node_02__tcomputation_taskTB' in read-only section .text’
/usr/bin/ld: /home/darek/work/dsa_dev/ada_src/dsa/x86_64-unknown-linux-gnu/stubs/calc_node_01.o: in function calc_node_01__tcomputation_taskVIP': calc_node_01.ads:(.text+0x7ca8): undefined reference to calc_node_01__tcomputation_taskTB’
/usr/bin/ld: /home/darek/work/dsa_dev/ada_src/dsa/x86_64-unknown-linux-gnu/stubs/calc_node_02.o: in function calc_node_02__tcomputation_taskVIP': calc_node_02.ads:(.text+0x7ca8): undefined reference to calc_node_02__tcomputation_taskTB’
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
gprbuild: link of partition.adb failed


I tried to compile the code (and the PolyORB) with the ‘-fPIC’ and ‘-static-pie’ but it did not change the outcome. I got the same link error.

Looks like the system cannot find the function. The ‘nm’ command gives:


nm -g dsa/x86_64-unknown-linux-gnu/stubs/calc_node_01.o
U ada__exceptions__exception_occurrenceIP
U ada__exceptions__triggered_by_abort
U ada__strings__unbounded__adjust__2
U ada__strings__unbounded__finalize__2
0000000000000878 T calc_node_01__create_computation_task
0000000000000010 D calc_node_01_E
0000000000007cf2 T calc_node_01___elabs
000000000000325c T calc_node_01__free_computation_task
0000000000000000 B calc_node_01___master
0000000000007bcc T calc_node_01__P2sIP
0000000000000000 T calc_node_01__R11s__get_rci_package_ref
0000000000000280 R calc_node_01__R11s__rci_name
0000000000000008 B calc_node_01__R11s__version
U calc_node_01S
00000000000048ac T calc_node_01__start_task
0000000000006d60 T calc_node_01__stop_task
0000000000000012 D calc_node_01__tcomputation_taskE
U calc_node_01__tcomputation_taskTB
0000000000007bde T calc_node_01__tcomputation_taskVIP
0000000000000018 D calc_node_01__tcomputation_taskZ

….


Did anybody encounter this kind of issues when using the DSA subsystem ?

Thanks to all for comments & suggestions, and help!

Take care.

Darek

Glad to hear there is some progress :slight_smile: .

It’s quite late here atm, so I will try to take a look at the other probs tomorrow morning.

It would be good if you could make the project code publicly available in some git repo, so we can test it ourselves.

You copy-pasted a build log for something you refer to as /PolyORB/examples/dsa/echo.

I expect more, e.g. a link to the repository, but apparently, this is an acceptable way to ask for help nowadays.
.

This error happens in GNAT Programming Studio when you try to compile a spec-file which requires a body.

I have used the command line to build it. It seems that the example is incomplete. Right?

Thanks.

For the sake of completeness, this the link to the repository: GitHub - AdaCore/PolyORB: PolyORB provides a uniform solution to build distributed applications relying either on middleware standards

I meant can you put your code into a git repo and publish it, so I can clone the repo and test it here.

https://codeberg.org/ or github, perhaps.

Also, this would allow us to discuss each problem in the Issues section of the public repo, so as not to flood this topic/forum with highly specific project related chat.

Finally, I am on the ‘ada’ channel of the libera irc network, if you prefer to chat directly in real-time.

EDIT: Changed from ‘freenode’ irc network to ‘libera’.

I just created a public repo with the code on the gitlab:

Darek Maksimiuk / dsa_dev · GitLab

Hi @darek,

I think I have solved both problems.

In your gpr file, add …

package Compiler is
for Default_Switches (“Ada”) use (“-fPIC”);
end Compiler;

package Linker is
for Default_Switches (“Ada”) use (“-fPIC”);
end Linker;

This occurs due to declaring a task type in an RCI *spec*. Atm, I’m not sure if that is a polyorb problem or a general DSA restriction.

To fix it …

In the ‘calc_node’ packages, move the task type declaration (and type tComputation_Task_Acc) to the package bodies. Also in the bodies, declare this global variable …

Comp_Task : tComputation_Task_Acc;

Remove all ‘Comp_Task : in out tComputation_Task_Acc;’ parameters from your procedures. in both specs and bodies. In ‘run_dsa.adb’, remove those corresponding arguments. Also rid …

N_01 : CN_01.tComputation_Task_Acc;
N_02 : CN_02.tComputation_Task_Acc;

(They serve no purpose, and certainly can’t be dereferenced in a DSA build, since they are from different partitions (address spaces)).

Finally, you might do well to use a generic for your ‘calc_node’ packages, as they are identical (as you mentioned).

I think that is all. Let me know how you get on :slight_smile: .

Oh, also move your ‘poly_dsa.cfg’ up to the main root folder and invoke …

$ po_gnatdist -P poly_dsa.gpr poly_dsa.cfg

… to do the dsa builld.

Okay, so it is a DSA restriction.

Ada 2022 RM — E.2.3(5–6)

E.2.3(5/5)
A remote call interface library unit shall not contain the declaration of a variable, a task, a protected type, or a protected object.

E.2.3(6/5)
A remote call interface library unit shall not contain the declaration of a type extension, nor a declaration of a private type whose full view is a type extension.

Probably, it should show up as a gnatmake error, rather than the ambiguous linker error later on. I wonder if it is worth reporting as a bug ?

While you guys are on this topic. Can somebody summarize steps to implement the distributed annex from scratch? Which files must be provided for GNAT to recognize an implementation of. I have a ready to use implementation of for interprocess communication but have no idea how to convince GNAT to take it.

1 Like

Hi Dimitry,

I have not touched the internals of GNAT regarding the distribution annex. However, I would start looking into exp_dist and exp_smem. Also, I would assume that the implementation should be portable enough as PolyORB existed outside. But that does not mean it would be easy…

I think Tucker once told about implementing some more modern methods such as ZeroMQ or something like that as the communication layer. But I cant recall more.

Best regards,
Fer

1 Like