-
Notifications
You must be signed in to change notification settings - Fork 123
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
301 additions
and
5 deletions.
There are no files selected for viewing
Submodule spectra
updated
5 files
+0 −1 | .gitignore | |
+5 −5 | CMakeLists.txt | |
+1 −1 | README.md | |
+0 −1 | cmake/spectra-config.cmake.in | |
+0 −1 | examples/.gitignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
############################################################ | ||
# | ||
# An example of Makefile for the course on | ||
# Advanced Programming for Scientific Computing | ||
# It should be modified for adapting it to the various examples | ||
# | ||
############################################################ | ||
# | ||
# The environmental variable PACS_ROOT should be set to the | ||
# root directory where the examples reside. In practice, the directory | ||
# where this file is found. The resolution of PACS_ROOT is made in the | ||
# Makefile.h file, where other important variables are also set. | ||
# The only user defined variable that must be set in this file is | ||
# the one indicating where Makefile.h resides | ||
|
||
MAKEFILEH_DIR=../../.. | ||
# | ||
include $(MAKEFILEH_DIR)/Makefile.inc | ||
# | ||
# You may have an include file also in the current directory | ||
# | ||
-include Makefile.inc | ||
|
||
# | ||
# The general setting is as follows: | ||
# mains are identified bt main_XX.cpp | ||
# all other files are XX.cpp | ||
# | ||
|
||
# get all files *.cpp | ||
SRCS=$(wildcard *.cpp) | ||
# get the corresponding object file | ||
OBJS = $(SRCS:.cpp=.o) | ||
# get all headers in the working directory | ||
HEADERS=$(wildcard *.hpp) | ||
# | ||
exe_sources=$(filter main%.cpp,$(SRCS)) | ||
EXEC=$(exe_sources:.cpp=) | ||
|
||
#========================== ORA LA DEFINIZIONE DEGLI OBIETTIVI | ||
.phony= all clean distclean doc | ||
|
||
.DEFAULT_GOAL = all | ||
|
||
all: $(DEPEND) $(EXEC) | ||
|
||
clean: | ||
$(RM) -f $(EXEC) $(OBJS) | ||
|
||
distclean: | ||
$(MAKE) clean | ||
$(RM) -f ./doc $(DEPEND) | ||
$(RM) *.out *.bak *~ | ||
|
||
doc: | ||
doxygen $(DOXYFILE) | ||
|
||
$(EXEC): $(OBJS) | ||
|
||
$(OBJS): $(SRCS) | ||
|
||
$(DEPEND): $(SRCS) | ||
-\rm $(DEPEND) | ||
for f in $(SRCS); do \ | ||
$(CXX) $(STDFLAGS) $(CPPFLAGS) -MM $$f >> $(DEPEND); \ | ||
done | ||
|
||
-include $(DEPEND) | ||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# The std::span utility # | ||
`std::span` is a utility introduced in C++20 that provides a view over a contiguous sequence of elements. It is a lightweight, non-owning reference to an array or a portion of an array, which can be used to pass arrays or parts of arrays to functions without copying the data. | ||
|
||
Its main purpose is to provide a safe and efficient way to work with arrays and array-like containers, such as `std::array`, `std::vector`, and built-in arrays, without the need to copy or manage memory. | ||
|
||
## Key Features ## | ||
- Non-owning: `std::span` does not own the elements it references, meaning it does not manage the memory of the underlying data. | ||
- Contiguous: The elements referenced by `std::span` are guaranteed to be contiguous in memory. | ||
- Bounds-safe: Provides bounds-checked access to elements when using the at method. | ||
- Flexible: Can be constructed from arrays, `std::array`, `std::vector`, and other contiguous containers. | ||
|
||
## Usage ## | ||
Here are some common use cases and examples of how to use `std::span`: | ||
|
||
Creating a std::span | ||
You can create a std::span from various types of containers: | ||
```cpp | ||
#include <span> | ||
#include <vector> | ||
#include <array> | ||
#include <iostream> | ||
|
||
int main() { | ||
// From a C-style array | ||
int arr[] = {1, 2, 3, 4, 5}; | ||
std::span<int> span1(arr); | ||
|
||
// From a std::array | ||
std::array<int, 5> stdArr = {1, 2, 3, 4, 5}; | ||
std::span<int> span2(stdArr); | ||
|
||
// From a std::vector | ||
std::vector<int> vec = {1, 2, 3, 4, 5}; | ||
std::span<int> span3(vec); | ||
|
||
// Output elements | ||
for (int i : span1) { | ||
std::cout << i << " "; | ||
} | ||
std::cout << std::endl; | ||
|
||
return 0; | ||
} | ||
``` | ||
Slicing a std::span | ||
You can create sub-spans (slices) from an existing std::span: | ||
```cpp | ||
#include <span> | ||
#include <iostream> | ||
|
||
int main() { | ||
int arr[] = {1, 2, 3, 4, 5}; | ||
std::span<int> span(arr); | ||
|
||
// Create a sub-span from index 1 to 3 | ||
std::span<int> subSpan = span.subspan(1, 3); | ||
|
||
// Output elements of the sub-span | ||
for (int i : subSpan) { | ||
std::cout << i << " "; | ||
} | ||
std::cout << std::endl; | ||
|
||
return 0; | ||
} | ||
``` | ||
|
||
|
||
Bounds-checked Access | ||
You can access elements with bounds checking using the at method: | ||
```cpp | ||
#include <span> | ||
#include <iostream> | ||
|
||
int main() { | ||
int arr[] = {1, 2, 3, 4, 5}; | ||
std::span<int> span(arr); | ||
|
||
try { | ||
std::cout << span.at(2) << std::endl; // Outputs: 3 | ||
std::cout << span.at(5) << std::endl; // Throws std::out_of_range | ||
} catch (const std::out_of_range& e) { | ||
std::cerr << "Out of range error: " << e.what() << std::endl; | ||
} | ||
|
||
return 0; | ||
} | ||
``` | ||
|
||
## Conclusion ## | ||
`std::span` is a versatile and efficient utility for working with contiguous sequences of elements in C++. It provides a safe and convenient way to pass arrays and array-like containers to functions without copying data, making it a valuable addition to the C++ standard library. | ||
## What do I learn Here? ## | ||
A nice utility that can be helpsul when is necessary to mix C-style arrays and C++ contiguos containers. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#include <iostream> | ||
#include <span> | ||
#include <vector> | ||
|
||
void | ||
printSpan(std::span<int> span) | ||
{ | ||
for(int element : span) | ||
{ | ||
std::cout << element << " "; | ||
} | ||
std::cout << std::endl; | ||
} | ||
|
||
int | ||
main() | ||
{ | ||
// a C=style array | ||
int numbers[] = {1, 2, 3, 4, 5}; | ||
|
||
// Create a span from the array | ||
std::span<int> span(numbers); | ||
|
||
// Print the elements of the span | ||
printSpan(span); | ||
|
||
// Modify the elements of the span | ||
for(int &element : span) | ||
{ | ||
element *= 2; | ||
} | ||
|
||
// Print the modified elements of the span | ||
printSpan(span); | ||
|
||
std::cout << "The original array is also modified\n"; | ||
// and I can print it using printSpan! | ||
printSpan(numbers); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#ifndef HH_PARALLEL_FOR_HPP_HH | ||
#define HH_PARALLEL_FOR_HPP_HH | ||
#include <algorithm> | ||
#include <concepts> | ||
#include <execution> | ||
#include <ranges> | ||
namespace apsc | ||
{ | ||
/** | ||
* @brief Executes a parallel loop over a range of indices using the specified | ||
* execution policy. | ||
* | ||
* This function executes a parallel loop over a range of indices specified by | ||
* `first` and `last`, using the specified execution policy `p`. The loop body | ||
* is defined by the callable object `f`, which takes an index as its argument. | ||
* | ||
* @tparam Policy The type of the execution policy. | ||
* @tparam Index The type of the loop indices. | ||
* @tparam F The type of the callable object representing the loop body. | ||
* | ||
* @param p The execution policy to use for parallel execution. | ||
* @param first The first index of the loop range (inclusive). | ||
* @param last The last index of the loop range (exclusive). | ||
* @param f The callable object representing the loop body. | ||
*/ | ||
template <typename Policy, std::integral Index, typename F> | ||
requires requires(Policy p, Index i, F f) { | ||
f(i); | ||
requires std::is_execution_policy_v<std::remove_cvref_t<Policy>>; | ||
} | ||
auto | ||
parallel_for(Policy &&p, Index first, Index last, F f) -> void | ||
{ | ||
auto r = std::ranges::views::iota(first, last); | ||
std::for_each(p, r.begin(), r.end(), std::move(f)); | ||
} | ||
} // namespace apsc | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#include "parallel_for.hpp" | ||
#include <iostream> | ||
|
||
// Test case 1: Parallel loop with lambda function | ||
void | ||
test_case_1() | ||
{ | ||
std::cout << "Test case 1:\n"; | ||
std::vector sum = {1, -1, 3, 4, 7, 9, 11}; | ||
auto add_to_sum = [&sum](int i) { sum[i] += 2; }; | ||
apsc::parallel_for(std::execution::par, std::size_t{0}, sum.size(), | ||
add_to_sum); | ||
std::cout << "computed values " << std::endl; | ||
for(int i : sum) | ||
{ | ||
std::cout << i << " "; | ||
} | ||
std::cout << std::endl; | ||
} | ||
|
||
// Test case 2: Parallel loop with function object | ||
struct MultiplyByTwo | ||
{ | ||
std::vector<int> v; | ||
void | ||
operator()(int i) | ||
{ | ||
v.push_back(i * 2); | ||
} | ||
}; | ||
|
||
void | ||
test_case_2() | ||
{ | ||
std::cout << "Test case 2:\n"; | ||
MultiplyByTwo m; | ||
apsc::parallel_for(std::execution::par, 0, 5, std::ref(m)); | ||
for(int i : m.v) | ||
{ | ||
std::cout << i << " "; | ||
} | ||
std::cout << std::endl; | ||
// Expected output: 0 2 4 6 8 | ||
} | ||
|
||
int | ||
main() | ||
{ | ||
test_case_1(); | ||
test_case_2(); | ||
return 0; | ||
} |
Submodule muparser
updated
3 files
+5 −12 | README.md | |
+1 −0 | include/muParserTemplateMagic.h | |
+2 −1 | src/muParserBase.cpp |