--

-- Copyright (C) 2011 Reto Buerki <reet@codelabs.ch>

-- Copyright (C) 2011 Adrian-Ken Rueegsegger <ken@codelabs.ch>

-- University of Applied Sciences Rapperswil

--

-- This program is free software: you can redistribute it and/or modify

-- it under the terms of the GNU General Public License as published by

-- the Free Software Foundation, either version 3 of the License, or

-- (at your option) any later version.

--

-- This program is distributed in the hope that it will be useful,

-- but WITHOUT ANY WARRANTY; without even the implied warranty of

-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

-- GNU General Public License for more details.

--

-- You should have received a copy of the GNU General Public License

-- along with this program. If not, see <http://www.gnu.org/licenses/>.

--

with

Ada.Text_IO

;

with

Ada.Numerics.Real_Arrays

;

with

CUDA.Autoinit

;

with

CUDA.Compiler

;

pragma

Unreferenced

(

CUDA

.

Autoinit

);

procedure

Add

is

use

CUDA

;

package

Real_Vector_Args

is new

Compiler.Arg_Creators

(

Data_Type

=>

);

use

Real_Vector_Args

;

N

:

constant

:=

32

*

1024

;

A

:

Ada

.

Numerics

.

Real_Arrays

.

Real_Vector

:=

(

1

..

N

=>

2.0

);

B

:

Ada

.

Numerics

.

Real_Arrays

.

Real_Vector

:=

(

1

..

N

=>

2.0

);

C

:

aliased

Ada

.

Numerics

.

Real_Arrays

.

Real_Vector

:=

(

1

..

N

=>

0.0

);

Src

:

Compiler

.

Source_Module_Type

;

Func

:

Compiler

.

Function

_Type

;

Module

:

Compiler

.

Module_Type

;

begin

Src

:=

Compiler

.

Create

(

Preamble

=>

"#define N"

&

N

'

Img

,

Operation

=>

"__global__ void add( float *a, float *b, float *c ) {"

&

" int tid = blockIdx.x;"

&

" while (tid < N) {"

&

" c[tid] = a[tid] + b[tid];"

&

" tid += gridDim.x;"

&

"}}"

);

Module

:=

Compiler

.

Compile

(

Source

=>

Src

);

Func

:=

Compiler

.

Get_Function

(

Module

=>

Module

,

Name

=>

"add"

);

Func

.

Call

(

Args

=>

(

1

=>

In_Arg

(

Data

=>

A

),

2

=>

In_Arg

(

Data

=>

B

),

3

=>

Out_Arg

(

Data

=>

C

'

Access

)));

for

I

in

C

'

Range

loop

if

C

(

I

)

/=

A

(

I

)

+

B

(

I

)

then

raise

Program_Error

with

"Results mismatch"

;

end

if

;

end

loop

;

Ada

.

Text_IO

.

Put_Line

(

"Calculation successful"

);

end

Add

;