Skip to content
Open

Ada #686

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5b4aa1f
getting started
jeffhammond Mar 25, 2023
28b6b0f
arg parsing
jeffhammond Mar 25, 2023
407a0b0
nstream
jeffhammond Mar 25, 2023
933ee4b
nstream parse okay
jeffhammond Mar 25, 2023
2fd3d94
nstream
jeffhammond Mar 25, 2023
1099f21
nstream
jeffhammond Mar 25, 2023
8b6aa52
figured out how to measure time
jeffhammond Apr 6, 2023
8447af9
small change
jeffhammond Apr 6, 2023
68e80d5
cleanup
jeffhammond Apr 9, 2023
d7b69fa
array version start
jeffhammond Apr 9, 2023
4ef1167
array version start
jeffhammond Apr 9, 2023
09fe1f9
heap allocation version works
jeffhammond Apr 9, 2023
585ce4d
Long_Integer because heap allows bigger arrays
jeffhammond Apr 9, 2023
9dd8cef
transpose work in progress
jeffhammond Apr 9, 2023
cca3937
Merge branch 'ParRes:default' into ada
jeffhammond Jul 19, 2023
2c8051d
Merge branch 'ParRes:main' into ada
jeffhammond Dec 6, 2024
6a8b473
Merge branch 'ParRes:main' into ada
jeffhammond Apr 17, 2025
26f1a25
Merge branch 'main' into ada
jeffhammond Apr 17, 2025
76572ae
Merge branch 'ada' of https://github.com/jeffhammond/PRK into ada
jeffhammond Apr 17, 2025
7571005
Merge branch 'main' into ada
jeffhammond Sep 27, 2026
f5c8801
Finish ADA: add p2p and stencil, fix transpose (was not transposing),…
jeffhammond Sep 27, 2026
53a17b1
ADA: replace nstream with the heap-allocated nstream_array implementa…
jeffhammond Sep 27, 2026
f8e0e99
ADA: remove hello.adb and args.adb (scratch, not PRK kernels)
jeffhammond Sep 27, 2026
74a032e
Add CMake support for ADA
jeffhammond Sep 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,9 @@ func.c
*.log3

ADA/*.ali
ADA/args
ADA/hello
ADA/nstream
ADA/nstream_array
ADA/p2p
ADA/stencil
ADA/transpose

C1z/nstream
Expand Down
67 changes: 67 additions & 0 deletions ADA/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#
# CMake port of ADA/Makefile. CMake has no native Ada language support
# (no LANGUAGES Ada for project()/enable_language()), so this drives
# gnatmake directly via add_custom_command(), the same approach used
# elsewhere in this repo for build steps CMake can't natively express
# (e.g. common/Stencil/loop_gen code generation in the C-family ports).
#
# Standalone project: `cd ADA && cmake -S . -B build` works on its own.
# Also add_subdirectory()'d from the repo root.
#

cmake_minimum_required(VERSION 3.18)
project(PRK_ADA NONE)
enable_testing()

find_program(GNATMAKE_EXECUTABLE gnatmake)

if(NOT GNATMAKE_EXECUTABLE)
message(STATUS "ADA: skipped, no gnatmake (GNAT Ada compiler) found")
return()
endif()

message(STATUS "ADA: gnatmake found at ${GNATMAKE_EXECUTABLE}")

# prk_ada_executable(<name>)
# Compiles <name>.adb with gnatmake into ${CMAKE_CURRENT_BINARY_DIR}/<name>,
# keeping generated .o/.ali files in the build tree (gnatmake -D) rather
# than polluting the source directory. The custom target is named
# ada_<name>, not <name>: target names must be unique across the whole
# combined root project (every PRK language directory has its own p2p/
# stencil/etc.), same reasoning as every other language's CMakeLists.txt
# in this repo -- but since this is a custom target/command, not a real
# add_executable(), there's no OUTPUT_NAME to reconcile: the produced
# binary is simply named <name> directly.
function(prk_ada_executable name)
set(_src "${CMAKE_CURRENT_LIST_DIR}/${name}.adb")
set(_out "${CMAKE_CURRENT_BINARY_DIR}/${name}")
add_custom_command(
OUTPUT "${_out}"
COMMAND "${GNATMAKE_EXECUTABLE}" -D "${CMAKE_CURRENT_BINARY_DIR}" -p
"${_src}" -o "${_out}"
DEPENDS "${_src}"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "Building Ada ${name} with gnatmake")
add_custom_target(ada_${name} ALL DEPENDS "${_out}")
endfunction()

function(prk_ada_test test_name)
set(multiValueArgs COMMAND)
cmake_parse_arguments(PAT "" "" "${multiValueArgs}" ${ARGN})
add_test(NAME ${test_name} COMMAND ${PAT_COMMAND})
set_tests_properties(${test_name} PROPERTIES TIMEOUT 30)
endfunction()

prk_ada_executable(nstream)
prk_ada_executable(p2p)
prk_ada_executable(stencil)
prk_ada_executable(transpose)

# --- CTest: same invocations used to verify each kernel by hand ---------

prk_ada_test(ada_nstream COMMAND "${CMAKE_CURRENT_BINARY_DIR}/nstream" 10 16000000)
prk_ada_test(ada_p2p COMMAND "${CMAKE_CURRENT_BINARY_DIR}/p2p" 10 1000 1000)
prk_ada_test(ada_transpose COMMAND "${CMAKE_CURRENT_BINARY_DIR}/transpose" 10 1000)
prk_ada_test(ada_stencil_star COMMAND "${CMAKE_CURRENT_BINARY_DIR}/stencil" 10 1000)
prk_ada_test(ada_stencil_grid COMMAND "${CMAKE_CURRENT_BINARY_DIR}/stencil" 10 1000 grid)
prk_ada_test(ada_stencil_star_r4 COMMAND "${CMAKE_CURRENT_BINARY_DIR}/stencil" 10 1000 star 4)
4 changes: 2 additions & 2 deletions ADA/Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
AC = gnat
ACFLAGS = make

all: hello args nstream nstream_array transpose
all: nstream p2p stencil transpose

%: %.adb
$(AC) $(ACFLAGS) $< -o $@

clean:
-rm -f *.i *.o *.ali
-rm -f hello args nstream nstream_array transpose
-rm -f nstream p2p stencil transpose

42 changes: 0 additions & 42 deletions ADA/args.adb

This file was deleted.

6 changes: 0 additions & 6 deletions ADA/hello.adb

This file was deleted.

73 changes: 37 additions & 36 deletions ADA/nstream.adb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ procedure Nstream is
Ada.Real_Time,
Ada.Command_line;

-- GNAT Integer = int32_t, Long_Integer = int64_t
Iterations : Integer := 10;
Length : Integer := 1_000_000;
Length : Long_Integer := 1_000_000;

Scalar : constant := 3.0;

Expand All @@ -26,63 +27,67 @@ begin
Iterations := Integer'Value(Argument(1));
end if;
if Argument_Count > 1 then
Length := Integer'Value(Argument(2));
Length := Long_Integer'Value(Argument(2));
end if;

if Iterations < 2 then
if Iterations < 1 then
Put_Line("Iteration count must be greater than " & Integer'Image(Iterations) );
end if;

Put_Line("Number of iterations =" & Integer'Image(Iterations) );
Put_Line("Vector length =" & Integer'Image(Length) );
Put_Line("Vector length =" & Long_Integer'Image(Length) );

declare
type Vector is array(1..Length) of Float;

I : Integer := 0;
A : Vector;
B : Vector;
C : Vector;
-- Heap-allocated (via an access type), not a plain local array:
-- a stack-declared array of this size does not reliably fit on
-- the default 8MB stack once Length grows past a few hundred
-- thousand elements. Double precision throughout, matching the
-- "double precision" convention of the other language ports.
type Long_Float_Array is array(Long_Integer range <>) of Long_Float
with Default_Component_Value => 0.0;
type Long_Float_Array_Access is access Long_Float_Array;
A : Long_Float_Array_Access := new Long_Float_Array(1..Length);
B : Long_Float_Array_Access := new Long_Float_Array(1..Length);
C : Long_Float_Array_Access := new Long_Float_Array(1..Length);

T0, T1 : Time;
DT : Time_Span;

US : constant Time_Span := Microseconds(US => Iterations);

K : Integer := 0;
AR : Float := 0.0;
BR : Float := 2.0;
CR : Float := 2.0;
Asum : Float := 0.0;
AR : Long_Float := 0.0;
BR : Long_Float := 2.0;
CR : Long_Float := 2.0;
Asum : Long_Float := 0.0;

AvgTime : Duration;
Bytes : Integer := Float'Size / 8;
Bytes : Long_Integer;
Nstream_us : Integer;
Nstream_time : Float;
Bandwidth : Float;
Nstream_time : Long_Float;
Bandwidth : Long_Float;

begin

-- initialization

for I in 1..Length Loop
A(I) := Float(0);
B(I) := Float(2);
C(I) := Float(2);
A(I) := 0.0;
B(I) := 2.0;
C(I) := 2.0;
end Loop;

-- run the experiment

for K in 0..Iterations Loop

if K = 1 then
T0 := Clock;
end if;

for I in 1..Length Loop
A(I) := A(I) + B(I) + Scalar * C(I);
end Loop;

end Loop;
T1 := Clock;
DT := T1 - T0;
Expand All @@ -98,22 +103,18 @@ begin
end Loop;

if Asum /= 0.0 then
Put_Line("Asum=" & Float'Image(Asum) );
Put_Line("Asum=" & Long_Float'Image(Asum) );
else
Put_Line("Solution validates");
Bytes := Bytes * Length * 4;
-- 4 array touches (read A,B,C + write A) * 8 bytes each
Bytes := Length * Long_Float'Size / 2;
Nstream_us := DT / US; -- this is per iteration now, thanks to US
Nstream_time := Float(Nstream_us) / Float(1000000);
Put_Line("Avg time (s): " & Float'Image(Nstream_time));
Bandwidth := Float(Bytes) / Float(Nstream_us);
Put_Line("Rate (MB/s): " & Float'Image(Bandwidth));
-- archived for posterity
--Put_Line("Bytes=" & Integer'Image(Bytes) );
AvgTime := To_Duration(DT);
Put_Line("Total Time: " & Duration'Image(AvgTime) & " seconds");
Nstream_time := Long_Float(Nstream_us) / Long_Float(1_000_000);
Put_Line("Avg time (s): " & Long_Float'Image(Nstream_time));
Bandwidth := Long_Float(Bytes) / Long_Float(Nstream_us);
Put_Line("Rate (MB/s): " & Long_Float'Image(Bandwidth));
end if;

end;

end Nstream;

Loading
Loading