From bb11fdb99829ebf4f8ca673d0a99a4ea1886042d Mon Sep 17 00:00:00 2001 From: Theofilos Manitaras Date: Tue, 16 Mar 2021 13:58:25 +0100 Subject: [PATCH 1/6] Add '-pthread' to the multithreaded tutorial test --- docs/tutorial_basics.rst | 21 +++++++++------------ tutorials/basics/hellomp/hellomp1.py | 2 +- tutorials/basics/hellomp/hellomp2.py | 2 +- tutorials/basics/hellomp/hellomp3.py | 2 +- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/docs/tutorial_basics.rst b/docs/tutorial_basics.rst index 79439d747d..6a9d23eac3 100644 --- a/docs/tutorial_basics.rst +++ b/docs/tutorial_basics.rst @@ -1,13 +1,4 @@ -========================================== - Tutorial 1: Getting Started with ReFrame -========================================== - -.. versionadded:: 3.1 - -This tutorial will give you a first overview of ReFrame and will acquaint you with its basic concepts. -We will start with a simple "Hello, World!" test running with the default configuration and we will expand the example along the way. -We will also explore performance tests and port our tests to an HPC cluster. -The examples of this tutorial can be found under :obj:`tutorials/basics/`. +========================================== Tutorial 1: Getting Started with ReFrame ========================================== .. versionadded:: 3.1 This tutorial will give you a first overview of ReFrame and will acquaint you with its basic concepts. We will start with a simple "Hello, World!" test running with the default configuration and we will expand the example along the way. We will also explore performance tests and port our tests to an HPC cluster. The examples of this tutorial can be found under :obj:`tutorials/basics/`. Getting Ready @@ -415,7 +406,7 @@ We extend our C++ "Hello, World!" example to print the greetings from multiple t :language: cpp :lines: 6- -This program takes as argument the number of threads it will create and it uses ``std::thread``, which is C++11 addition, meaning that we will need to pass ``-std=c++11`` to our compilers. +This program takes as argument the number of threads it will create and it uses ``std::thread``, which is C++11 addition, meaning that we will need to pass ``-std=c++11``, as well as ``-pthread`` to our compilers. Here is the corresponding ReFrame test, where the new concepts introduced are highlighted: .. code-block:: console @@ -427,11 +418,17 @@ Here is the corresponding ReFrame test, where the new concepts introduced are hi :lines: 6- :emphasize-lines: 11-13 +.. note:: + + The ``-pthread`` option is needed to compile applications using ``std::thread`` with GCC and Clang. + In case of a different compiler, the above option may need to be adjusted. + + ReFrame delegates the compilation of a test to a *build system*, which is an abstraction of the steps needed to compile the test. Build systems take also care of interactions with the programming environment if necessary. Compilation flags are a property of the build system. If not explicitly specified, ReFrame will try to pick the correct build system (e.g., CMake, Autotools etc.) by inspecting the test resources, but in cases as the one presented here where we need to set the compilation flags, we need to specify a build system explicitly. -In this example, we instruct ReFrame to compile a single source file using the ``-std=c++11 -Wall`` compilation flags. +In this example, we instruct ReFrame to compile a single source file using the ``-std=c++11 -pthread -Wall`` compilation flags. Finally, we set the arguments to be passed to the generated executable in :attr:`executable_opts `. diff --git a/tutorials/basics/hellomp/hellomp1.py b/tutorials/basics/hellomp/hellomp1.py index c8528e0d40..1396ce7937 100644 --- a/tutorials/basics/hellomp/hellomp1.py +++ b/tutorials/basics/hellomp/hellomp1.py @@ -14,6 +14,6 @@ def __init__(self): self.valid_prog_environs = ['*'] self.sourcepath = 'hello_threads.cpp' self.build_system = 'SingleSource' - self.build_system.cxxflags = ['-std=c++11', '-Wall'] + self.build_system.cxxflags = ['-std=c++11', '-pthread', '-Wall'] self.executable_opts = ['16'] self.sanity_patterns = sn.assert_found(r'Hello, World\!', self.stdout) diff --git a/tutorials/basics/hellomp/hellomp2.py b/tutorials/basics/hellomp/hellomp2.py index 98170df46c..bba2483d2f 100644 --- a/tutorials/basics/hellomp/hellomp2.py +++ b/tutorials/basics/hellomp/hellomp2.py @@ -15,7 +15,7 @@ def __init__(self): self.sourcepath = 'hello_threads.cpp' self.executable_opts = ['16'] self.build_system = 'SingleSource' - self.build_system.cxxflags = ['-std=c++11', '-Wall'] + self.build_system.cxxflags = ['-std=c++11', '-pthread', '-Wall'] num_messages = sn.len(sn.findall(r'\[\s?\d+\] Hello, World\!', self.stdout)) self.sanity_patterns = sn.assert_eq(num_messages, 16) diff --git a/tutorials/basics/hellomp/hellomp3.py b/tutorials/basics/hellomp/hellomp3.py index 5f53ddbac3..ccf1d9d125 100644 --- a/tutorials/basics/hellomp/hellomp3.py +++ b/tutorials/basics/hellomp/hellomp3.py @@ -16,7 +16,7 @@ def __init__(self): self.executable_opts = ['16'] self.build_system = 'SingleSource' self.build_system.cppflags = ['-DSYNC_MESSAGES'] - self.build_system.cxxflags = ['-std=c++11', '-Wall'] + self.build_system.cxxflags = ['-std=c++11', '-pthread', '-Wall'] num_messages = sn.len(sn.findall(r'\[\s?\d+\] Hello, World\!', self.stdout)) self.sanity_patterns = sn.assert_eq(num_messages, 16) From 84219ea9c42786818640bbf7df7d5ae16f2e9684 Mon Sep 17 00:00:00 2001 From: Theofilos Manitaras Date: Wed, 17 Mar 2021 09:22:03 +0100 Subject: [PATCH 2/6] Address PR comments --- docs/tutorial_basics.rst | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/tutorial_basics.rst b/docs/tutorial_basics.rst index 6a9d23eac3..d38f835fcb 100644 --- a/docs/tutorial_basics.rst +++ b/docs/tutorial_basics.rst @@ -1,4 +1,13 @@ -========================================== Tutorial 1: Getting Started with ReFrame ========================================== .. versionadded:: 3.1 This tutorial will give you a first overview of ReFrame and will acquaint you with its basic concepts. We will start with a simple "Hello, World!" test running with the default configuration and we will expand the example along the way. We will also explore performance tests and port our tests to an HPC cluster. The examples of this tutorial can be found under :obj:`tutorials/basics/`. +========================================== + Tutorial 1: Getting Started with ReFrame +========================================== + + .. versionadded:: 3.1 + +This tutorial will give you a first overview of ReFrame and will acquaint you with its basic concepts. +We will start with a simple "Hello, World!" test running with the default configuration and we will expand the example along the way. +We will also explore performance tests and port our tests to an HPC cluster. +The examples of this tutorial can be found under :obj:`tutorials/basics/`. Getting Ready @@ -406,7 +415,7 @@ We extend our C++ "Hello, World!" example to print the greetings from multiple t :language: cpp :lines: 6- -This program takes as argument the number of threads it will create and it uses ``std::thread``, which is C++11 addition, meaning that we will need to pass ``-std=c++11``, as well as ``-pthread`` to our compilers. +This program takes as argument the number of threads it will create and it uses ``std::thread``, which is C++11 addition, meaning that we will need to pass ``-std=c++11`` and ``-pthread`` to our compilers. Here is the corresponding ReFrame test, where the new concepts introduced are highlighted: .. code-block:: console From 61e3d17889fc8db9626ddaf06f5ad65589ff5829 Mon Sep 17 00:00:00 2001 From: Theofilos Manitaras Date: Wed, 17 Mar 2021 09:26:01 +0100 Subject: [PATCH 3/6] Small formatting fix --- docs/tutorial_basics.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorial_basics.rst b/docs/tutorial_basics.rst index 10914ffda9..5d5b089a39 100644 --- a/docs/tutorial_basics.rst +++ b/docs/tutorial_basics.rst @@ -2,7 +2,7 @@ Tutorial 1: Getting Started with ReFrame ========================================== - .. versionadded:: 3.1 +.. versionadded:: 3.1 This tutorial will give you a first overview of ReFrame and will acquaint you with its basic concepts. We will start with a simple "Hello, World!" test running with the default configuration and we will expand the example along the way. From e7647b5820aa71ecd3c02f7bb8b4557119c0f126 Mon Sep 17 00:00:00 2001 From: Theofilos Manitaras Date: Tue, 30 Mar 2021 17:21:52 +0200 Subject: [PATCH 4/6] Add '-pthread' flag to tutorial checks for GNU & Clang --- docs/tutorial_basics.rst | 21 +++++++++++++++++---- tutorials/basics/hellomp/hellomp1.py | 8 +++++++- tutorials/basics/hellomp/hellomp2.py | 8 +++++++- tutorials/basics/hellomp/hellomp3.py | 9 ++++++++- 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/docs/tutorial_basics.rst b/docs/tutorial_basics.rst index 5d5b089a39..dabb2ef0da 100644 --- a/docs/tutorial_basics.rst +++ b/docs/tutorial_basics.rst @@ -417,7 +417,7 @@ We extend our C++ "Hello, World!" example to print the greetings from multiple t :language: cpp :lines: 6- -This program takes as argument the number of threads it will create and it uses ``std::thread``, which is C++11 addition, meaning that we will need to pass ``-std=c++11`` and ``-pthread`` to our compilers. +This program takes as argument the number of threads it will create and it uses ``std::thread``, which is a C++11 addition, meaning that we will need to pass ``-std=c++11`` to our compilers. Here is the corresponding ReFrame test, where the new concepts introduced are highlighted: .. code-block:: console @@ -429,17 +429,30 @@ Here is the corresponding ReFrame test, where the new concepts introduced are hi :lines: 6- :emphasize-lines: 11-13 + +In order to compile applications using ``std::thread`` with GCC and Clang, the ``-pthread`` option has to be passed to the compiler. +Since the above option might not be valid for other compilers, we use pipeline hooks to differentiate based on the programming environment as follows: + +.. code-block:: python + + @rfm.run_before('compile') + def setpthreadsflag(self): + environ = self.current_environ.name + if environ in {'clang', 'gnu'}: + self.build_system.cxxflags += ['-pthread'] + + .. note:: - The ``-pthread`` option is needed to compile applications using ``std::thread`` with GCC and Clang. - In case of a different compiler, the above option may need to be adjusted. + The pipeline hooks are covered in more detail in a following tutorial section. + For a detailed coverage of the regression test pipeline, please refer to :doc:`pipeline`. ReFrame delegates the compilation of a test to a *build system*, which is an abstraction of the steps needed to compile the test. Build systems take also care of interactions with the programming environment if necessary. Compilation flags are a property of the build system. If not explicitly specified, ReFrame will try to pick the correct build system (e.g., CMake, Autotools etc.) by inspecting the test resources, but in cases as the one presented here where we need to set the compilation flags, we need to specify a build system explicitly. -In this example, we instruct ReFrame to compile a single source file using the ``-std=c++11 -pthread -Wall`` compilation flags. +In this example, we instruct ReFrame to compile a single source file using the ``-std=c++11 -pthread -Wall`` (for GCC and Clang). Finally, we set the arguments to be passed to the generated executable in :attr:`executable_opts `. diff --git a/tutorials/basics/hellomp/hellomp1.py b/tutorials/basics/hellomp/hellomp1.py index 1396ce7937..a5f75183d2 100644 --- a/tutorials/basics/hellomp/hellomp1.py +++ b/tutorials/basics/hellomp/hellomp1.py @@ -14,6 +14,12 @@ def __init__(self): self.valid_prog_environs = ['*'] self.sourcepath = 'hello_threads.cpp' self.build_system = 'SingleSource' - self.build_system.cxxflags = ['-std=c++11', '-pthread', '-Wall'] + self.build_system.cxxflags = ['-std=c++11', '-Wall'] self.executable_opts = ['16'] self.sanity_patterns = sn.assert_found(r'Hello, World\!', self.stdout) + + @rfm.run_before('compile') + def setpthreadsflag(self): + environ = self.current_environ.name + if environ in {'clang', 'gnu'}: + self.build_system.cxxflags += ['-pthread'] diff --git a/tutorials/basics/hellomp/hellomp2.py b/tutorials/basics/hellomp/hellomp2.py index bba2483d2f..481c7fd993 100644 --- a/tutorials/basics/hellomp/hellomp2.py +++ b/tutorials/basics/hellomp/hellomp2.py @@ -15,7 +15,13 @@ def __init__(self): self.sourcepath = 'hello_threads.cpp' self.executable_opts = ['16'] self.build_system = 'SingleSource' - self.build_system.cxxflags = ['-std=c++11', '-pthread', '-Wall'] + self.build_system.cxxflags = ['-std=c++11', '-Wall'] num_messages = sn.len(sn.findall(r'\[\s?\d+\] Hello, World\!', self.stdout)) self.sanity_patterns = sn.assert_eq(num_messages, 16) + + @rfm.run_before('compile') + def setpthreadsflag(self): + environ = self.current_environ.name + if environ in {'clang', 'gnu'}: + self.build_system.cxxflags += ['-pthread'] diff --git a/tutorials/basics/hellomp/hellomp3.py b/tutorials/basics/hellomp/hellomp3.py index ccf1d9d125..fd5d93eca4 100644 --- a/tutorials/basics/hellomp/hellomp3.py +++ b/tutorials/basics/hellomp/hellomp3.py @@ -16,7 +16,14 @@ def __init__(self): self.executable_opts = ['16'] self.build_system = 'SingleSource' self.build_system.cppflags = ['-DSYNC_MESSAGES'] - self.build_system.cxxflags = ['-std=c++11', '-pthread', '-Wall'] + self.build_system.cxxflags = ['-std=c++11', '-Wall'] num_messages = sn.len(sn.findall(r'\[\s?\d+\] Hello, World\!', self.stdout)) self.sanity_patterns = sn.assert_eq(num_messages, 16) + + @rfm.run_before('compile') + def setpthreadsflag(self): + environ = self.current_environ.name + if environ in {'clang', 'gnu'}: + self.build_system.cxxflags += ['-pthread'] + From 97e63b53be33e1d6bb1bc3ec1997e37ac4aa30ba Mon Sep 17 00:00:00 2001 From: Theofilos Manitaras Date: Tue, 30 Mar 2021 17:26:44 +0200 Subject: [PATCH 5/6] Remove blank line --- tutorials/basics/hellomp/hellomp3.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tutorials/basics/hellomp/hellomp3.py b/tutorials/basics/hellomp/hellomp3.py index fd5d93eca4..3eba5ddd6a 100644 --- a/tutorials/basics/hellomp/hellomp3.py +++ b/tutorials/basics/hellomp/hellomp3.py @@ -26,4 +26,3 @@ def setpthreadsflag(self): environ = self.current_environ.name if environ in {'clang', 'gnu'}: self.build_system.cxxflags += ['-pthread'] - From c88a7b3202f96d175e8deb6ba9ad97dab75c1811 Mon Sep 17 00:00:00 2001 From: Theofilos Manitaras Date: Fri, 2 Apr 2021 11:30:22 +0200 Subject: [PATCH 6/6] Address PR comments --- docs/tutorial_basics.rst | 9 ++++----- tutorials/basics/hellomp/hellomp1.py | 2 +- tutorials/basics/hellomp/hellomp2.py | 2 +- tutorials/basics/hellomp/hellomp3.py | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/tutorial_basics.rst b/docs/tutorial_basics.rst index dabb2ef0da..3fb6ab9406 100644 --- a/docs/tutorial_basics.rst +++ b/docs/tutorial_basics.rst @@ -436,7 +436,7 @@ Since the above option might not be valid for other compilers, we use pipeline h .. code-block:: python @rfm.run_before('compile') - def setpthreadsflag(self): + def set_threading_flags(self): environ = self.current_environ.name if environ in {'clang', 'gnu'}: self.build_system.cxxflags += ['-pthread'] @@ -444,15 +444,14 @@ Since the above option might not be valid for other compilers, we use pipeline h .. note:: - The pipeline hooks are covered in more detail in a following tutorial section. - For a detailed coverage of the regression test pipeline, please refer to :doc:`pipeline`. + The pipeline hooks, as well as the regression test pipeline itself, are covered in more detail later on in the tutorial. ReFrame delegates the compilation of a test to a *build system*, which is an abstraction of the steps needed to compile the test. Build systems take also care of interactions with the programming environment if necessary. Compilation flags are a property of the build system. If not explicitly specified, ReFrame will try to pick the correct build system (e.g., CMake, Autotools etc.) by inspecting the test resources, but in cases as the one presented here where we need to set the compilation flags, we need to specify a build system explicitly. -In this example, we instruct ReFrame to compile a single source file using the ``-std=c++11 -pthread -Wall`` (for GCC and Clang). +In this example, we instruct ReFrame to compile a single source file using the ``-std=c++11 -pthread -Wall`` compilation flags. Finally, we set the arguments to be passed to the generated executable in :attr:`executable_opts `. @@ -1094,7 +1093,7 @@ Let's see and comment the changes: First of all, we need to add the new programming environments in the list of the supported ones. Now there is the problem that each compiler has its own flags for enabling OpenMP, so we need to differentiate the behavior of the test based on the programming environment. For this reason, we define the flags for each compiler in a separate dictionary (``self.flags``) and we set them in the :func:`setflags` pipeline hook. -Let's explain what is this all about. +We have first seen the pipeline hooks in the multithreaded "Hello, World!" example and now we explain them in more detail. When ReFrame loads a test file, it instantiates all the tests it finds in it. Based on the system ReFrame runs on and the supported environments of the tests, it will generate different test cases for each system partition and environment combination and it will finally send the test cases for execution. During its execution, a test case goes through the *regression test pipeline*, which is a series of well defined phases. diff --git a/tutorials/basics/hellomp/hellomp1.py b/tutorials/basics/hellomp/hellomp1.py index a5f75183d2..9925a9ed22 100644 --- a/tutorials/basics/hellomp/hellomp1.py +++ b/tutorials/basics/hellomp/hellomp1.py @@ -19,7 +19,7 @@ def __init__(self): self.sanity_patterns = sn.assert_found(r'Hello, World\!', self.stdout) @rfm.run_before('compile') - def setpthreadsflag(self): + def set_threading_flags(self): environ = self.current_environ.name if environ in {'clang', 'gnu'}: self.build_system.cxxflags += ['-pthread'] diff --git a/tutorials/basics/hellomp/hellomp2.py b/tutorials/basics/hellomp/hellomp2.py index 481c7fd993..48524d8b28 100644 --- a/tutorials/basics/hellomp/hellomp2.py +++ b/tutorials/basics/hellomp/hellomp2.py @@ -21,7 +21,7 @@ def __init__(self): self.sanity_patterns = sn.assert_eq(num_messages, 16) @rfm.run_before('compile') - def setpthreadsflag(self): + def set_threading_flags(self): environ = self.current_environ.name if environ in {'clang', 'gnu'}: self.build_system.cxxflags += ['-pthread'] diff --git a/tutorials/basics/hellomp/hellomp3.py b/tutorials/basics/hellomp/hellomp3.py index 3eba5ddd6a..c6441545b6 100644 --- a/tutorials/basics/hellomp/hellomp3.py +++ b/tutorials/basics/hellomp/hellomp3.py @@ -22,7 +22,7 @@ def __init__(self): self.sanity_patterns = sn.assert_eq(num_messages, 16) @rfm.run_before('compile') - def setpthreadsflag(self): + def set_threading_flags(self): environ = self.current_environ.name if environ in {'clang', 'gnu'}: self.build_system.cxxflags += ['-pthread']