Skip to content

Commit

Permalink
fmk - updating day 4 and 5 assingments
Browse files Browse the repository at this point in the history
  • Loading branch information
fmckenna committed Jun 7, 2023
1 parent e6986ac commit 727dfb9
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 55 deletions.
73 changes: 47 additions & 26 deletions sphynx/source/assignment_C2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,32 @@ C: Assignments Day 2
====================


Today we have several problems for you to tackle.
Parts should look and feel familiar from Day 1, though we will add more features as we go.
Those problems are modeled after exercises in Python and, thus, allow you to learn how data structures
compare when transitioning from python to C (and later C++).
Today we have several problems for you to tackle. Parts should look and feel familiar from Day 1, though we will add more features as we go.



Problem 1: Reviewing the stress transformation problem
Problem 1: DGEMM
------------------------------------------------------
Navigate to **/code/c/ExerciseDay2/ex2-1/** to find another solution for the stress transformation problem. The main difference to Frank's solution is that this one places functions in separate files, as
well as adds a header file that contains the definition of the function without its implementation.

Compiling this version requires multiple steps:
Navigate to **/assignments/C-Day2/matMul**. Instead of a single file, there are multiple files. One of these files, **BlasDGEMM.c**, invokes the BLAS dgemm function and requires that the application be linked to the **BLAS** library. Compiling and linking the applications would require you to find the path to the blas libraries. In addition the multiple .c files would require multiple compilation commands. Compiling this version requires multiple steps:

.. code::
gcc stresstransform.c -c
gcc exercise2-1.c stresstransform.o -lm
gcc myDGEMM.c -c
gcc blasDGEMM.c -c
gcc matMul.c myDGEMM.o blasDGEMM.o -lm -/pathtoblaslibrary -o matMul
And you can run the executable as

.. code::
./a.out
./matMul
Imagine doing this for many more files, usually tens to hundreds. That would be painstaking and
inefficient and very error prone. Software engineers developed several tools to simplify and automate the compile
process. One of those tools is **cmake**, a member of the **make** family of tools. You find a
configuration file names **CMakeList.txt** in the source folder. The configuration
file is a plain text file, so you can and should check out how it is written.


The compile process now becomes

1. a configuration step - done only once or every time you are adding a file to the project. Inside the
Expand All @@ -44,6 +38,7 @@ source folder, execute
$ mkdir build
$ cd build
$ cmake ..
$ cmake --build .
This will check your system for compilers and other development tool and create a **Makefile** in each
Expand All @@ -59,15 +54,32 @@ type

.. code::
$ make
$ cmake --build .
to recompile all portions necessary and link all parts to one executable. That process remains exactly the
same regardless of the number of files in your project. Give it a try and see how convenient this is
especially for projects provided by somebody else.



Now that you can compile the **matMul** application, you will find it does not work! You are required to fix the **matMul.c** program to allocate memory for the A, B, C and C1 arrays. These arrays are double arrays to hold square, n by n, matrices that are required to be stored in column major order. Some code is required lines 29 through 32. You should also throw in **4** lines ariund line 59.

.. literalinclude:: ./assignments/c2/matMul.c
:language: c
:linenos:

After fixing the matMul.c file, you need to edit the **myDGEMM.c** file and place in their code to perform the matrix-matrix operation: C = C + A * B;

.. math::
c_{ij}= c_{ij} + a_{i1} b_{1j} + a_{i2} b_{2j} +\cdots+ a_{in} b_{nj} = c_{ij} + \sum_{k=1}^n a_{ik}b_{kj}
.. literalinclude:: ./assignments/c2/myDGEMM.c
:language: c
:linenos:


.. note::

The CMake process created another executabble, **benchmark**. If you run it you will see how your implementation compares in performance against the vendor supplied blas function. It is probably a pretty bad comparison. Try improving the performance. You can play with different compile options, or a revised algorithm, e.g. black matrix-multiply.


Problem 2: Using structures
Expand All @@ -85,7 +97,7 @@ write it. Your task in this exercise is to create a structure
} STRESS ;
and modify the code from the previous exercise to utilize the much easier to read data structure provided
by this :code:`struct`. Use the code skeleton provided in **/code/c/ExerciseDay2/ex2-2** to develop that
by this :code:`struct`. Use the code skeleton provided in **/assignments/C_Day2/stressTransformationStruct** to develop that
code. The included :code:`CMakeList.txt` shall be used to compile your code.

.. note::
Expand Down Expand Up @@ -122,7 +134,8 @@ images using the computed values. A more efficient way is to use C to do the an
an easily readable file, and use specialized tools for the post-processing. One common and simple format
is **CSV** (comma-separated-values), which van be read easily by MATLAB, python, or Excel.

**Your task**: modify the code given in **/code/c/ExerciseDay2/ex2-3** to

**Your task**: modify the code given in **/assignments/C-Day2/stressTransformFile/ex2-3/** to

1. Take one argument :math:`\Delta\theta` in degrees after the name of the executable, defining the increment at
which transformed stress values shall be written:
Expand Down Expand Up @@ -174,12 +187,11 @@ Once your code outputs the information, run it once more and save the results to
Problem 4: Writing to a binary file
-----------------------------------


Modify the code generated in the previous exercise to write a binary file names *mohrcircle.dta* instead
Modify the code generated in the previous exercise to write a binary file named *mohrcircle.dta* instead
of the formatted ASCII data. The data shall be exported in clocks composed of :code:`double theta`
followed by a block of :code:`STRESS` (or the three components of stress as :code:`double`).

You may be working of your code or use the provided code skeleton in **/code/c/ExerciseDay2/ex2-4**.
You may be working of your code or use the provided code skeleton in **/assignments/C-Day2/stressTensorFile/ex2-4**.

This time, your code should be totally silent on execution. The only sign of success will be the creation
of the data file. For the next steps, run your program with the following parameters:
Expand Down Expand Up @@ -236,11 +248,15 @@ of the data file. For the next steps, run your program with the following parame



Problem 5: Reading From a binary file and Memory Allocation
-----------------------------------------------------------
Problem 5: Reading From a CSV file, Memory Allocation & Writing to Binary
-------------------------------------------------------------------------


Reading of data from files and placing them into containers such as Vectors is easy if you know the size of the data you are reading. If this is unknown the problem becomes more tricky. The solution presented on slide 22 worked for a small number of inputs, but failed with a segmentation fault for larger problems. You are to fix the problem. A copy of the offending file **file3.c** has been placed in the directory binaryFile along with two files. The program can handle the first **small.txt**, it will fail with the second **big.txt**. Can you make the program work. The solution will test your understanding of file I/O, memory management and pointers.

Initial code is provided in the **/assignments/C-Day2/binaryFile** directory.

Reading of data from files and placing them into containers such as Vectors is easy if you know the size of the data you are reading. If this is unknown the problem becomes more tricky. The solution presented on slide 22 worked for a small number of inputs, but failed with a segmentation fault for larger problems. You are to fix the problem. A copy of the offending file **file3.c** has been placed in the directory ex2-5 along with two files. The program can handle the first **small.txt**, it will fail with the second **big.txt**. Can you make the program work. The solution will test your understanding of file I/O, memory management and pointers.
At end of the program, you are asked to modify the code so that the results of the two vectors are ouput to a binary file. Output the contents of **vector1** followed by **vector2**.

The **file3.c** is as shown below. You need to put some code to replace comment at the line 41.

Expand All @@ -255,11 +271,16 @@ The **small.txt** file is as shown below.

.. note::

No cmake or Makefile has been provided. You can compile the file with icc or whatever compiler you are using. The program takes a single input, the file to read. To compile and test the program, issue the following at the terminal prompt.
No cmake or Makefile has been provided. You can compile the file with icc or whatever compiler you are using. The program takes two inputs, the file to read and the file to write. To compile and test the program, issue the following at the terminal prompt. When done compare the file sizes of the binary file to the text file.


.. code::
icc file3.c -o file3
./file2 small.txt
./file2 big.txt
./file2 big.txt
.. note::

Give some thought as to how you would open the file and read back in the two vectors. If you have some time, write a program to do and have that program write the contents of the binary files to a csv file.
19 changes: 8 additions & 11 deletions sphynx/source/assignment_C4.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
C: Assignments Day 4
====================

Today we have two problems for you to tackle. They both parallelize the **pi.c** code you developed for day 1. Both programs will need to be compiled at one of the TACC supercomputers.
Today we are going to parallelize the **pi.c** code you developed for day 1. to run at TACC you will need to use either **idev** or **sbatch**.

The figure below shows an method to compute **pi** by numerical integration. We would like you to implement that computation in a **C** program.

Expand All @@ -12,7 +12,7 @@ The figure below shows an method to compute **pi** by numerical integration. We
Computation of pi numerically


The solution `pi.c <https://github.com/NHERI-SimCenter/SimCenterBootcamp2022/tree/master/code/c/ExerciseDay1/assignments/pi.c>`_ can be found on github. The contents of that file is presented here:
The solution `pi.c' is in the solitions/C-Day1/pi folder. The contents of that file is presented here:

.. literalinclude:: ./assignments/c4/pi.c
:language: c
Expand All @@ -39,9 +39,9 @@ The solution `pi.c <https://github.com/NHERI-SimCenter/SimCenterBootcamp2022/tr

.. warning::

Our solution of **pi.c** as written as a loop dependency which may need to revise for the second problem.
Our solution of **pi.c** as written as a loop dependency which may need to revise for tomorrows OpenMPI problem.

Problem 1: Parallelize using **MPI**
Problem 1: Parallelize **pi.c** using **MPI**
------------------------------------

You are to modify the **pi.c** application and run it to use mpi. I have included a few files in code/parallel/ExercisesDay4/ex1 to help you. They include **pi.c** above, gather1.c and a submit.sh script. **gather1.c** was presented in the video, and us shown below:
Expand All @@ -56,12 +56,9 @@ The submit script is as shown below.
:linenos:


Problem 2: Parallelize using OpenMP
-----------------------------------

You are to modify the **pi.c** application and run it to use mpi. I have included a few files in code/parallel/ExercisesDay4/ex1 to help you. They include **pi.c** above and submitPI.sh script. **submitPI.sh** is as shown:

.. literalinclude:: ./solutions/c4/submitPI.sh
:linenos:
Problem 2: Bonus Parallelize your **matMul** solution using **MPI**
-------------------------------------------------------------------

If you want a more complicated problem to parallelize, I suggest parallelizing you matMul application from Day 2.


12 changes: 12 additions & 0 deletions sphynx/source/assignment_C5.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@
C: Assignments Day 5
====================

Problem 1: Parallelize using OpenMP
-----------------------------------

You are to modify the **pi.c** application and run it to use mpi. I have included a few files in code/parallel/ExercisesDay4/ex1 to help you. They include **pi.c** above and submitPI.sh script. **submitPI.sh** is as shown:

.. literalinclude:: ./solutions/c4/submitPI.sh
:linenos:


Problem 2: Additional Exercise JUST for Frank
---------------------------------------------

The purpose of these exercises is to set it up so that you are able to run a parallel application on Frontera or Stampede2 by issuing commands in the terminal of your desktop using your DesignSafe account and resources. Time permitting we will share the applications with fellow classmates. The advantage of being able to do this from a terminal is convenience and speed, e.g. you no longer will be required to login and find a token, cd to appropriate directories, edit submit scripts, and so on. Ultimately, as you progress in your careers you will begin to understand, the ability to share your work is one of the really great advantages provided.

There are **5** steps to the exercise today. The steps follow the videos presented for today's class (these are enclosed in hints herein). The exercises are outlined below the **hint**.
Expand Down
4 changes: 2 additions & 2 deletions sphynx/source/assignments.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ Each assignment typically includes one or more of the following.
assignment_C2
# assignment_C2_solution
assignment_C3
# assignment_C4
assignment_C4_solution
assignment_C4
# assignment_C4_solution
assignment_C5
assignment_day1
assignment_day2
Expand Down
36 changes: 20 additions & 16 deletions sphynx/source/assignments/c2/file3.c
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@

/*******************************************************************
* program to read values from a file,
* with each line being csv list of int and two double
*
* program fails if num lines > 100
* Major flaw will cause data to be overwritten outside array
* bounds if #lines > 100 & will ultimataly lead to a segmentation fault
*
* Exerise is to fix flaw WITHOUT just setting maxVectorSize incredibly large
*
* written: fmk
******************************************************************* */
// program to read values from a file, each file a csv list of int and two double
// written: fmk

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {

if (argc != 2) {
fprintf(stdout, "ERROR correct usage appName inputFile\n");
if (argc != 3) {
fprintf(stdout, "ERROR correct usage appName inputFile outputBinaryFile\n");
return -1;
}

//
// read from ascii file
//

FILE *filePtr = fopen(argv[1],"r");

Expand All @@ -38,9 +32,19 @@ int main(int argc, char **argv) {
vectorSize++;

if (vectorSize == maxVectorSize) {
/* some code needed here .. programming exercise */
// some code needed here I think .. programming exercise
}
}

fclose(filePtr);

fclose(filePtr);
//
// write data to binary file
//

FILE *filePtrB = fopen(argv[2],"wb");

// some missing code to write vector1, followed by vector 2

fclose(filePtrB);
}
64 changes: 64 additions & 0 deletions sphynx/source/assignments/c2/matMul.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

extern void myDGEMM(int n, double *A, double *B, double *C);
extern void blasDGEMM(int n, double* A, double* B, double* C);

void fill(double* p, int n) {
for (int i = 0; i < n; ++i)
p[i] = (double)rand() / (double)RAND_MAX ;
}

/* The benchmarking program */
int main(int argc, char** argv) {

if (argc != 2) {
printf("Correct usage: app matrixDimension?\n");
exit(0);
}

// get matrix size
int n = atoi(argv[1]);
n = fabs(n);
if (n == 0)
n = 10;

int result = 0;

double *A = 0; // << SOME CODE HERE
double *B = 0; // << SOME CODE HERE
double *C = 0; // << SOME CODE HERE
double *C1 = 0; // << SOME CODE HERE

if (A == 0 || B == 0 || C == 0 || C1 == 0) {
printf("NO MMEORY ALLOCATED FOR ARRAYS\n");
exit(0);
}

fill(A, n * n);
fill(B, n * n);
fill(C, n * n);

for (int i=0; i<n*n; i++)
C1[i]=C[i];

blasDGEMM(n, A, B, C);

myDGEMM(n, A, B, C1);

// check they are the same .. take into account there will be differences due to roundoff
for (int j=0; j<n*n; j++) {
double diff = C1[j] - C[j];
double error = fabs(diff/C[j]);
if (error > 1e-10) {
result = 1;
}
}

// GOOD PRACTICE TO PUT 4 LINES of CODE HERE


printf("%d\n", result);
return 0;
}
13 changes: 13 additions & 0 deletions sphynx/source/assignments/c2/myDGEMM.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const char* dgemm_desc = "Naive, three-loop dgemm.";

/*
* This routine performs a dgemm operation
* C := C + A * B
* where A, B, and C are lda-by-lda matrices stored in column-major format.
* On exit, A and B maintain their input values.
*
* NOTE: Fortran storage: C(i,j) = C[i + j*n]
*/
void myDGEMM(int n, double* A, double* B, double* C) {
return;
}

0 comments on commit 727dfb9

Please sign in to comment.