Wednesday, 11 January 2017

OpenMp implementation of the Dining philosophers problem

Dining philosophers problem:

Five silent philosophers sit at a round table with bowls of spaghetti. Forks are placed between each pair of adjacent philosophers.
Each philosopher must alternately think and eat. However, a philosopher can only eat spaghetti when they have both left and right forks. Each fork can be held by only one philosopher and so a philosopher can use the fork only if it is not being used by another philosopher. After an individual philosopher finishes eating, they need to put down both forks so that the forks become available to others. A philosopher can take the fork on their right or the one on their left as they become available, but cannot start eating before getting both forks.
Eating is not limited by the remaining amounts of spaghetti or stomach space; an infinite supply and an infinite demand are assumed.
The problem is how to design a discipline of behavior (a concurrent algorithm) such that no philosopher will starve; i.e., each can forever continue to alternate between eating and thinking, assuming that no philosopher can know when others may want to eat or think


Here is the link for the OpenMp implementation of the Dining philosophers problem: (See the comments for explanation)

https://github.com/DHEERAJRK/Parallel-computing/blob/master/opmdining.c

Monday, 9 January 2017

CUDA Programming Basics

CUDA Programming Model Basics:

The CUDA programming model is a heterogeneous model in which both the CPU and GPU are used. In CUDA, the host refers to the CPU and its memory, while the device refers to the GPU and its memory. Code run on the host can manage memory on both the host and device, and also launches kernels which are functions executed on the device. These kernels are executed by many GPU threads in parallel.
Given the heterogeneous nature of the CUDA programming model, a typical sequence of operations for a CUDA C program is:
  1. Declare and allocate host and device memory.
  2. Initialize host data.
  3. Transfer data from the host to the device.
  4. Execute one or more kernels.
  5. Transfer results from the device to the host.
Let us look at some of the CUDA programs in c:

1. CUDA C program that add two array of elements and store the result in third array.


Problem statement: You are given two array with integer/real values, your task is to add to elements of both the array and store in another array.

Solution: The main task is to write CUDA kernel for that, writing kernel is not a big task. Let see how
Let say we have N elements in an array which is represent by “arraySize” (here it is = 5, change accordingly). We have two Function named addWithCuda (…); for invoking kernel and allocating memory on device.d_a and d_b is the device array for storing elements and d_c is the array which stores sum of both array d_a and d_b.
We launch arraysize number threads to add elements of array.
So, adding corresponding elements is quite easy. Just keep tracking the thread Id and we are done. We store id of thread within the block in “I” and adding both of the array element respectively

Here is the link for the code :



2. CUDA C program for Matrix Multiplication :


Problem statement:
To multiply two matrixes sufficient and necessary condition is "number of columns in matrix A = number of rows in matrix B".

Solution: 
Loop for each row in matrix A.Loop for each columns in matrix B and initialize output matrix C to 0. This loop will run for each rows of matrix A.Loop for each columns in matrix A.Multiply A[i,k] to B[k,j] and add this value to C[i,j]Return output matrix C.

Here is the link for the code :