Skip to content
Snippets Groups Projects
Commit 515af074 authored by zahoussem's avatar zahoussem
Browse files

README.md

parent 2632fbb2
No related branches found
No related tags found
No related merge requests found
......@@ -92,42 +92,27 @@ To get the execution sm for a given kernel, it can invoke :
# PRUDA usage by example
In this section, we will show how PRUDA can be used by calling two
periodic real-time tasks on the GPU. The first does the array sum and
the other for array multiplication.
First to use pruda, you must incluse the following header files:
```c
#include "../inc/user.h"
#include "../inc/tools.h"
#define N 8
__global__ void add( int *a, int *b, int *c ) {
printf("here 2 \n");
int tid = blockDim.x * blockIdx.x + threadIdx.x;
while (tid < N) {
c[tid] = a[tid] + b[tid];
tid += blockDim.x;
}
}
```
__global__ void mul( int *a, int *b, int *c, int h ) {
int tid = blockDim.x * blockIdx.x + threadIdx.x;
while (tid < N) {
c[tid] = a[tid] * b[tid];
tid += blockDim.x;
}
}
The user defines further its kernel in a classical way as follows:
```c
__global__ void add( int *a, int *b, int *c ) ... ;
__global__ void mul( int *a, int *b, int *c, int h ) ... ;
```
Further, the user writes it main function by first allocating the memory spaces of both CPU and GPU by the mean of malloc, cudaMalloc or cudaMallocManaged as in follows
int main(){
// initializing pointers
```c
int *a, *b, *c;
int *dev_a, *dev_b, *dev_c,ac;
......@@ -136,20 +121,30 @@ int main(){
b = (int*)malloc( N * sizeof(int) );
c = (int*)malloc( N * sizeof(int) );
... init vars
// allocating GPU memory
cudaMalloc( (void**)&dev_a, N * sizeof(int) );
cudaMalloc( (void**)&dev_b, N * sizeof(int) );
cudaMalloc( (void**)&dev_c, N * sizeof(int) );
```
// initializing the list of kernels
init_kernel_listing();
The user must now create kernels list. Therefore the user has a
predefined list in the file *user.cu*. The user calls
**get_listing()** and then initialize each kernel with the kernel
code, number of blocks and number of threads per block and finally the
kernel parameters as follows:
```c
// initializing the list of kernels init_kernel_listing();
create_kernel(std::get<1>(get_listing()),add,2,5,dev_a,dev_b,dev_c);
create_kernel(std::get<0>(get_listing()),mul,2,5,dev_a,dev_b,dev_c,ac);
```
Now all the GPU part has been initialezd. Now we configure the
scheduler it self. Therefore, we start by initializing task
scheduling parameters: deadline, period and periority and
encapsulating them in a pruda task as in the following examples:
```c
// gpu scheduling parameters for kernel add
struct gpu_sched_param add_p;
gb.period_us = 3000000;
......@@ -162,16 +157,19 @@ int main(){
ga.deadline_us= 6000000;
ga.priority = 15;
int gs_a = 10;
int bs_a = 5;
// declaring the gpu tasks (a container of params)
struct pruda_task_t * p_task_b = create_pruda_task(1, add_p);
struct pruda_task_t * p_task_a = create_pruda_task(0, mul_p);
```
int gs_b = 10;
int bs_b = 5;
We highlight that in the pruda task create, the first parameter is
the task id and **must** correspond to the same as in the kernel
list of **get_listing()**. Otherwise, compilation will fail for
type-inferences problems.
// declaring the gpu tasks (a container of params)
struct pruda_task_t * p_task_b = create_pruda_task(1, add_p, gs_a, bs_a);
struct pruda_task_t * p_task_a = create_pruda_task(0, mul_p, gs_b, bs_b);
Finally, the user must initilize the scheduler and add pruda tasks as follows :
```c
// initializing the scheduler with the desired staretgy and scheduling policy
init_scheduler(SINGLE, FP);
......@@ -184,11 +182,11 @@ int main(){
// (locks and synchronization params are under developpement)
create_cpu_threads();
...
}
```
```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment