Final exam Spring 2025 Q-and-A#

Date 5/8/2025. Time: 8 pm - 11 pm#

Number of exercises: 4. Each exercise has a maximum score.

In home directory of user hostadm, you need to create a new subdirectory, FINAL and a file within it, answers.txt, where you will be writing answers to the exam exercises.

In the file, first, put your name, then proceed with answering to the questions below.

All the exercises should be done on the VDI desktop.

1. Code compilation and Makefile (max score 6)#

In directory FINAL, copy/paste the source codes from the links below into files ode.c, lu.c, and hilbert.c respectively:

https://www.gnu.org/software/gsl/doc/html/ode-initval.html#examples

https://www.gnu.org/software/gsl/doc/html/linalg.html#examples

https://www.gnu.org/software/gsl/doc/html/eigen.html#examples

A) Compile source code and run the executable.

B) In the same directory, create a Makefile with targets:

  • ode.x

  • lu.x

  • hilbert.x

  • target all to compile all of the above,

  • target clean to remove the compilation products.


  • Answers:

A)

gcc -o ode.x  ode.c -lgsl
gcc -o lu.x lu.c -lgsl
gcc -o hilbert.x hilbert.c -lgsl

B)

lu.x: lu.c
        gcc -o lu.x lu.c -lgsl

ode.x: ode.c
        gcc -o ode.x  ode.c -lgsl

hilbert.x: hilbert.c
        gcc -o hilbert.x hilbert.c -lgsl

all: lu.x ode.x hilbert.x

clean:
        -@rm -f lu.x ode.x hilbert.x lu.x

2. Command grep and regular expressions (max score 6)#

A) By using command grep find the number of calls to gsl functions in file lu.c

B) By using command grep extract the lines in file lu.c that contain the values for a_data[] matrix and b_data[] vector like below:

double a_data[] = { 0.18, 0.60, 0.57, 0.96,
                    0.41, 0.24, 0.99, 0.58,
                    0.14, 0.30, 0.97, 0.66,
                    0.51, 0.13, 0.19, 0.85 };
                    
double b_data[] = { 1.0, 2.0, 3.0, 4.0 };

Hint: use the extended regular expressions for matching the groups of patterns with the floating point numbers. For example, a number, followed by a period, then another number, coma, space.


  • Answers:

A)

grep gsl lu.c  | wc -l

12

B) Three floating point numbers followed by , then space:

grep -E "([0-9]+\.[0-9]+\,[ \t]+){3}" lu.c

In the regular expressions above,

  • [0-9]+\.[0-9]+ matches any floating point number,

  • \, matches the coma,

  • [ \t]+ matches any number of spaces or tabs,

  • () groups the patterns together,

  • {3} matches the grouped pattern in () at least 3 times.


3. Python scripting (max score 8)#

Develop a python script that creates new file, lu_new.c, with replaced values for the matrix and the vector as shown below. In the script, you can import only one module, re.

double a_data[] = { 0.19, 0.61, 0.58, 0.97,
                    0.42, 0.25, 1.0, 0.59,
                    0.15, 0.31, 0.98, 0.67,
                    0.52, 0.14, 0.2, 0.86 };
                    
double b_data[] = { 1.1, 2.1, 3.1, 4.1 };

  • Answer:

#!/usr/bin/python3

import re, 

s1 = """
double a_data[] = { 0.19, 0.61, 0.58, 0.97,
                    0.42, 0.25, 1.0, 0.59,
                    0.15, 0.31, 0.98, 0.67,
                    0.52, 0.14, 0.2, 0.86 };
"""

s2 = "double b_data[] = { 1.1, 2.1, 3.1, 4.1 };"

lines = []
with open('lu.c','r') as f:
  for line in f:
    line = line.rstrip('\n')


    if 'double a_data' in line: #replace the line with s1
      lines.append(s1)
      continue

    if 'double b_data' in line: #replace the line with s2
      lines.append(s2)
      continue

    match = re.search(r'([0-9]+\.[0-9]+\,[ \t]+){3}', line) #skip the line if it matches a floating point number
    if match:
      continue

    lines.append(line)


#print(lines)

with open('lu_new.c','w') as f:
  for item in lines:
    f.write(f'{item}\n')

4. OpenMP (max score 6)#

Copy/paste the source code for matrix addition/substraction from the link below into file matrix.c:

https://www.sanfoundry.com/c-program-addition-subtraction-trace-matrices/

A) Compile it and run for 4 x 4 matrices.

B) By using OpenMP compiler directives, parallelize both the inner and the outer loops for computing arraysum[i][j], arraydiff[i][j], and trace. Be carefull with handling shared scalar variable trace.

C) Compile the code and run it with 2 threads.


Answers:

A)

gcc -o matrix.x matrix.c

B) Add the omp header file in the source code:

#include <omp.h>

The three parallel loops should look as follows in the code:



#pragma omp parallel for shared(arraysum,array1,array2,n,m) private(i,j) collapse(2)
for (i = 0; i < m; i++)
   {
       for (j = 0; j < n; j++)
                {
                    arraysum[i][j] = array1[i][j] + array2[i][j];
                }
   }

#pragma omp parallel for shared(arraydiff,array1,array2,n,m) private(i,j) collapse(2)
for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
                {
                    arraydiff[i][j] = array1[i][j] - array2[i][j];
                }
    }

#pragma omp parallel for shared(arr,n,m) private(i,j) collapse(2) reduction(+:trace)
for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
            {
                if (i == j)
                {
                    trace = trace + arr[i][j];
                }
            }
    }            

C)

gcc -fopenmp -o matrix.x matrix.c
export OMP_NUM_THREADS=2
./matrix.x