OpenMP support
What is OpenMP?
OpenMP is an API accessed by language directives to do multi threaded programming, see also http://www.openmp.org. Currently, there is only OpenMP syntax defined for C and Fortran. This page tries to collect some stuff to settle down pascal syntax for it.
Pascal syntax for OpenMP
Proposal 1
Foreword
At first, I must admit that some parts of the OpenMP specification I still don't understand. They did a terrible good job throwing away all common terms ever used in multi threading context, and invented their own ones.
Syntax vs. Compiler directives
OpenMP for C and C++ is implemented by using compiler directives mainly due to the reasons of source code compatibility (or: standards compliance). So a conforming program is intended to behave the same regardless if the actual compiler compiling the program supports those special pragmas or not.
For FreePascal I don't think this is the way to go, because first it changes comments into code and second, it makes the program far less readable. For C programs this doesn't seem to be an issue, if you get my meaning. But in my opinion, readability is a far more important issue than compatibility to older/different compilers. If all else fails, a preprocessor could be provided to strip out the parallel specific stuff, as has been suggested by Marco.
Well, enough talk, I start with the easier directives which are luckily the more fundamental ones.
parallel
The parallel
construct can only be used for a structured block. That means in Pascal it should be enclosed in some sort of begin
/end
pair anyway. So with this in mind, even the clauses that go with the original parallel
construct could possibly be supported in a clean and structured way.
So if you take a look at the A.4.1.c example of the OpenMP 2.5 specification, the Pascal version could look like this:
procedure SubDomain (var x : array of Float; istart : Integer; ipoints : Integer) var i : Integer; begin for i := 0 to ipoints - 1 do x[istart + i] := 123.456; end {SubDomain}; procedure Sub (var x : array of Float); // Variables declared here should haveshared
context. // This would include the function's parameters then... begin parallel // Variables declared here haveprivate
context. iam : Integer; nt : Integer; ipoints : Integer; begin // of parallel section iam := OMP.Get_Thread_Num; // OMP library calls. nt := OMP.Get_Num_Threads; ipoints := Length (x) div nt; // size of partition istart := iam * ipoints; // starting array index if iam = Pred (nt) then ipoints := Length (x) - istart; // last thread may do more SubDomain (x, istart, ipoints); end {parallel}; end {Sub}; var arr = array[0 .. 9999] of Float; begin // Main program Sub (arr); end.
I don't like the idea of declaring variables inside the actual statments, this looks very unpascalish. Maybe we can find a way around it. --FPK 10:22, 26 July 2006 (CEST)
I agree with Florian that this is not the way to go. Why not require all parallelizable code to be in local functions ? After all, that's almost what you are doing: declaring a local function. That would be a simple extension of the current syntax. You have access to all local variables; all you'd need is to add a parallel keyword to the local function declaration.
More constructs
To be continued...
Proposal 2: Using local functions
Instead of using new block types (like parallel), it uses a nested procedure, with the parallel modifier.
parallel
procedure SubDomain (var x : array of Float;
istart : Integer;
ipoints : Integer);
var
i : Integer;
begin
for i := 0 to ipoints - 1 do
x[istart + i] := 123.456;
end {SubDomain};
procedure Sub (var x : array of Float);
// Variables declared here should have shared
context.
// This would include the function's parameters then...
procedure ParallelBlock; parallel;
var
iam : Integer;
nt : Integer;
ipoints : Integer;
begin
iam := OMP.Get_Thread_Num; // OMP library calls.
nt := OMP.Get_Num_Threads;
ipoints := Length (x) div nt; // size of partition
istart := iam * ipoints; // starting array index
if iam = Pred (nt) then
ipoints := Length (x) - istart; // last thread may do more
SubDomain (x, istart, ipoints);
end;
begin
ParallelBlock;
end {Sub};
var
arr = array[0 .. 9999] of Float;
begin // Main program
Sub (arr);
end.
Proposal 3
<not yet done>