Add files via upload
This commit is contained in:
BIN
Lab04/HPC-Lab-04.pdf
Normal file
BIN
Lab04/HPC-Lab-04.pdf
Normal file
Binary file not shown.
BIN
Lab04/find_max
Normal file
BIN
Lab04/find_max
Normal file
Binary file not shown.
39
Lab04/find_max.cpp
Normal file
39
Lab04/find_max.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
/**
|
||||
* Function to find the maximum element in a vector using multiple threads.
|
||||
*
|
||||
* @param maxElement Reference to the variable where the maximum element will be stored.
|
||||
* @param v The vector of integers to search.
|
||||
*/
|
||||
int findMaxElement(const std::vector<int>& v) {
|
||||
int maxElement = std::numeric_limits<int>::min();
|
||||
// Find max element in the range
|
||||
for (int i = 0; i < v.size(); ++i) {
|
||||
if (v[i] > maxElement) {
|
||||
maxElement = v[i];
|
||||
}
|
||||
}
|
||||
return maxElement;
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Create a vector with some random values
|
||||
const int n = 10240;
|
||||
std::vector<int> v(n);
|
||||
v[0] = 1;
|
||||
for (int i = 1; i < n; ++i) {
|
||||
v[i] = (75 * v[i - 1]) % 65537;
|
||||
}
|
||||
|
||||
// Find the maximum element in the vector
|
||||
// This should be done in parallel using multiple threads
|
||||
int maxElement = findMaxElement(v);
|
||||
|
||||
std::cout << "Maximum element: " << maxElement << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
Lab04/find_max_threads
Normal file
BIN
Lab04/find_max_threads
Normal file
Binary file not shown.
61
Lab04/find_max_threads.cpp
Normal file
61
Lab04/find_max_threads.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <thread>
|
||||
|
||||
/**
|
||||
* Function to find the maximum element in a vector using multiple threads.
|
||||
*
|
||||
* @param maxElement Reference to the variable where the maximum element will be stored.
|
||||
* @param v The vector of integers to search.
|
||||
*/
|
||||
void findMaxElement(const std::vector<int>& v, const int start, const int end, int& result) {
|
||||
int maxElement = std::numeric_limits<int>::min();
|
||||
// Find max element in the range
|
||||
for (int i = start; i < end; ++i) {
|
||||
if (v[i] > maxElement) {
|
||||
maxElement = v[i];
|
||||
}
|
||||
}
|
||||
result = maxElement;
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Create a vector with some random values
|
||||
const int n = 10240;
|
||||
const int threadCounter = 4;
|
||||
std::vector<std::thread> threads;
|
||||
std::vector<int> res(4, 0);
|
||||
std::vector<int> v(n);
|
||||
v[0] = 1;
|
||||
for (int i = 1; i < n; ++i) {
|
||||
v[i] = (75 * v[i - 1]) % 65537;
|
||||
}
|
||||
|
||||
for(int i = 0; i < threadCounter; i++) {
|
||||
int start = n / threadCounter * i;
|
||||
int end = n / threadCounter * (i + 1);
|
||||
|
||||
threads.emplace_back(findMaxElement, std::ref(v), start, end, std::ref(res[i]));
|
||||
}
|
||||
|
||||
for(auto&t : threads) {
|
||||
t.join();
|
||||
}
|
||||
|
||||
int max = res[0];
|
||||
for(int i = 1; i < res.size(); i++) {
|
||||
if (max < res[i]){
|
||||
max = res[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Find the maximum element in the vector
|
||||
// This should be done in parallel using multiple threads
|
||||
//int maxElement = findMaxElement(v);
|
||||
|
||||
std::cout << "Maximum element: " << max << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
6
Lab04/helgrind.out
Normal file
6
Lab04/helgrind.out
Normal file
@@ -0,0 +1,6 @@
|
||||
==5173== Helgrind, a thread error detector
|
||||
==5173== Copyright (C) 2007-2017, and GNU GPL'd, by OpenWorks LLP et al.
|
||||
==5173== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
|
||||
==5173== Command: ./find_max_threads
|
||||
==5173== Parent PID: 5132
|
||||
==5173==
|
||||
184
Lab04/llvm.sh
Normal file
184
Lab04/llvm.sh
Normal file
@@ -0,0 +1,184 @@
|
||||
#!/bin/bash
|
||||
################################################################################
|
||||
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
# See https://llvm.org/LICENSE.txt for license information.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
################################################################################
|
||||
#
|
||||
# This script will install the llvm toolchain on the different
|
||||
# Debian and Ubuntu versions
|
||||
|
||||
set -eux
|
||||
|
||||
usage() {
|
||||
set +x
|
||||
echo "Usage: $0 [llvm_major_version] [all] [OPTIONS]" 1>&2
|
||||
echo -e "all\t\t\tInstall all packages." 1>&2
|
||||
echo -e "-n=code_name\t\tSpecifies the distro codename, for example bionic" 1>&2
|
||||
echo -e "-h\t\t\tPrints this help." 1>&2
|
||||
echo -e "-m=repo_base_url\tSpecifies the base URL from which to download." 1>&2
|
||||
exit 1;
|
||||
}
|
||||
|
||||
CURRENT_LLVM_STABLE=18
|
||||
BASE_URL="http://apt.llvm.org"
|
||||
|
||||
# Check for required tools
|
||||
needed_binaries=(lsb_release wget add-apt-repository gpg)
|
||||
missing_binaries=()
|
||||
for binary in "${needed_binaries[@]}"; do
|
||||
if ! which $binary &>/dev/null ; then
|
||||
missing_binaries+=($binary)
|
||||
fi
|
||||
done
|
||||
if [[ ${#missing_binaries[@]} -gt 0 ]] ; then
|
||||
echo "You are missing some tools this script requires: ${missing_binaries[@]}"
|
||||
echo "(hint: apt install lsb-release wget software-properties-common gnupg)"
|
||||
exit 4
|
||||
fi
|
||||
|
||||
# Set default values for commandline arguments
|
||||
# We default to the current stable branch of LLVM
|
||||
LLVM_VERSION=$CURRENT_LLVM_STABLE
|
||||
ALL=0
|
||||
DISTRO=$(lsb_release -is)
|
||||
VERSION=$(lsb_release -sr)
|
||||
UBUNTU_CODENAME=""
|
||||
CODENAME_FROM_ARGUMENTS=""
|
||||
# Obtain VERSION_CODENAME and UBUNTU_CODENAME (for Ubuntu and its derivatives)
|
||||
source /etc/os-release
|
||||
DISTRO=${DISTRO,,}
|
||||
case ${DISTRO} in
|
||||
debian)
|
||||
# Debian Trixie has a workaround because of
|
||||
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1038383
|
||||
if [[ "${VERSION}" == "unstable" ]] || [[ "${VERSION}" == "testing" ]] || [[ "${VERSION_CODENAME}" == "trixie" ]]; then
|
||||
CODENAME=unstable
|
||||
LINKNAME=
|
||||
else
|
||||
# "stable" Debian release
|
||||
CODENAME=${VERSION_CODENAME}
|
||||
LINKNAME=-${CODENAME}
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
# ubuntu and its derivatives
|
||||
if [[ -n "${UBUNTU_CODENAME}" ]]; then
|
||||
CODENAME=${UBUNTU_CODENAME}
|
||||
if [[ -n "${CODENAME}" ]]; then
|
||||
LINKNAME=-${CODENAME}
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# read optional command line arguments
|
||||
if [ "$#" -ge 1 ] && [ "${1::1}" != "-" ]; then
|
||||
if [ "$1" != "all" ]; then
|
||||
LLVM_VERSION=$1
|
||||
else
|
||||
# special case for ./llvm.sh all
|
||||
ALL=1
|
||||
fi
|
||||
OPTIND=2
|
||||
if [ "$#" -ge 2 ]; then
|
||||
if [ "$2" == "all" ]; then
|
||||
# Install all packages
|
||||
ALL=1
|
||||
OPTIND=3
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
while getopts ":hm:n:" arg; do
|
||||
case $arg in
|
||||
h)
|
||||
usage
|
||||
;;
|
||||
m)
|
||||
BASE_URL=${OPTARG}
|
||||
;;
|
||||
n)
|
||||
CODENAME=${OPTARG}
|
||||
if [[ "${CODENAME}" == "unstable" ]]; then
|
||||
# link name does not apply to unstable repository
|
||||
LINKNAME=
|
||||
else
|
||||
LINKNAME=-${CODENAME}
|
||||
fi
|
||||
CODENAME_FROM_ARGUMENTS="true"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "This script must be run as root!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
declare -A LLVM_VERSION_PATTERNS
|
||||
LLVM_VERSION_PATTERNS[9]="-9"
|
||||
LLVM_VERSION_PATTERNS[10]="-10"
|
||||
LLVM_VERSION_PATTERNS[11]="-11"
|
||||
LLVM_VERSION_PATTERNS[12]="-12"
|
||||
LLVM_VERSION_PATTERNS[13]="-13"
|
||||
LLVM_VERSION_PATTERNS[14]="-14"
|
||||
LLVM_VERSION_PATTERNS[15]="-15"
|
||||
LLVM_VERSION_PATTERNS[16]="-16"
|
||||
LLVM_VERSION_PATTERNS[17]="-17"
|
||||
LLVM_VERSION_PATTERNS[18]="-18"
|
||||
LLVM_VERSION_PATTERNS[19]="-19"
|
||||
LLVM_VERSION_PATTERNS[20]=""
|
||||
|
||||
if [ ! ${LLVM_VERSION_PATTERNS[$LLVM_VERSION]+_} ]; then
|
||||
echo "This script does not support LLVM version $LLVM_VERSION"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
LLVM_VERSION_STRING=${LLVM_VERSION_PATTERNS[$LLVM_VERSION]}
|
||||
|
||||
# join the repository name
|
||||
if [[ -n "${CODENAME}" ]]; then
|
||||
REPO_NAME="deb ${BASE_URL}/${CODENAME}/ llvm-toolchain${LINKNAME}${LLVM_VERSION_STRING} main"
|
||||
|
||||
# check if the repository exists for the distro and version
|
||||
if ! wget -q --method=HEAD ${BASE_URL}/${CODENAME} &> /dev/null; then
|
||||
if [[ -n "${CODENAME_FROM_ARGUMENTS}" ]]; then
|
||||
echo "Specified codename '${CODENAME}' is not supported by this script."
|
||||
else
|
||||
echo "Distribution '${DISTRO}' in version '${VERSION}' is not supported by this script."
|
||||
fi
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# install everything
|
||||
|
||||
if [[ ! -f /etc/apt/trusted.gpg.d/apt.llvm.org.asc ]]; then
|
||||
# download GPG key once
|
||||
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
|
||||
fi
|
||||
|
||||
if [[ -z "`apt-key list 2> /dev/null | grep -i llvm`" ]]; then
|
||||
# Delete the key in the old format
|
||||
apt-key del AF4F7421
|
||||
fi
|
||||
if [[ "${VERSION_CODENAME}" == "bookworm" ]]; then
|
||||
# add it twice to workaround:
|
||||
# https://github.com/llvm/llvm-project/issues/62475
|
||||
add-apt-repository -y "${REPO_NAME}"
|
||||
fi
|
||||
|
||||
add-apt-repository -y "${REPO_NAME}"
|
||||
apt-get update
|
||||
PKG="clang-$LLVM_VERSION lldb-$LLVM_VERSION lld-$LLVM_VERSION clangd-$LLVM_VERSION"
|
||||
if [[ $ALL -eq 1 ]]; then
|
||||
# same as in test-install.sh
|
||||
# No worries if we have dups
|
||||
PKG="$PKG clang-tidy-$LLVM_VERSION clang-format-$LLVM_VERSION clang-tools-$LLVM_VERSION llvm-$LLVM_VERSION-dev lld-$LLVM_VERSION lldb-$LLVM_VERSION llvm-$LLVM_VERSION-tools libomp-$LLVM_VERSION-dev libc++-$LLVM_VERSION-dev libc++abi-$LLVM_VERSION-dev libclang-common-$LLVM_VERSION-dev libclang-$LLVM_VERSION-dev libclang-cpp$LLVM_VERSION-dev libunwind-$LLVM_VERSION-dev"
|
||||
if test $LLVM_VERSION -gt 14; then
|
||||
PKG="$PKG libclang-rt-$LLVM_VERSION-dev libpolly-$LLVM_VERSION-dev"
|
||||
fi
|
||||
fi
|
||||
apt-get install -y $PKG
|
||||
8
Lab04/start_triad_bench.sh
Normal file
8
Lab04/start_triad_bench.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
#SBATCH --job-name=G5_triad_bench
|
||||
#SBATCH --nodes=4
|
||||
#SBATCH --ntasks=1
|
||||
|
||||
# Your script goes here
|
||||
./triad_bench
|
||||
BIN
Lab04/triad_bench
Normal file
BIN
Lab04/triad_bench
Normal file
Binary file not shown.
92
Lab04/triad_bench.cpp
Normal file
92
Lab04/triad_bench.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
std::vector<double> B(1000000, 1);
|
||||
std::vector<double> C(1000000, 2);
|
||||
std::vector<double> D(1000000, 3);
|
||||
|
||||
static double ownMethod(int n) {
|
||||
std::vector<double> A(n, 0);
|
||||
std::chrono::duration<double, std::milli> sumTime;
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
auto startTime = std::chrono::system_clock::now();
|
||||
for (int j = 0; j < n; ++j) {
|
||||
A[j] = B[j] + C[j] * D[j];
|
||||
}
|
||||
// prevent the compiler from optimizing everything away
|
||||
volatile double dummy = A[0];
|
||||
auto endTime = std::chrono::system_clock::now();
|
||||
sumTime += endTime - startTime;
|
||||
}
|
||||
double averageTime = sumTime.count() / 20;
|
||||
return averageTime;
|
||||
}
|
||||
|
||||
static std::vector<std::string> ownMethod2(int n) {
|
||||
std::vector<double> A(n, 0);
|
||||
std::vector<std::string> results(2);
|
||||
std::chrono::duration<double, std::milli> sumTime;
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
auto startTime = std::chrono::system_clock::now();
|
||||
for (int j = 0; j < n; ++j) {
|
||||
A[j] = B[j] + C[j] * D[j];
|
||||
}
|
||||
// prevent the compiler from optimizing everything away
|
||||
volatile double dummy = A[0];
|
||||
auto endTime = std::chrono::system_clock::now();
|
||||
sumTime += endTime - startTime;
|
||||
}
|
||||
double averageTime = sumTime.count() / 20;
|
||||
double flops = (2.0 * n) / (averageTime / 1000);
|
||||
results[0] = std::to_string(averageTime);
|
||||
results[1] = std::to_string(flops);
|
||||
return results;
|
||||
}
|
||||
|
||||
static void workerThread(int start, int end, int threadCount) {
|
||||
std::vector<std::vector<std::string>> outcomes;
|
||||
for (int i = start; i < end; i += 10) {
|
||||
outcomes.push_back(ownMethod2(i));
|
||||
}
|
||||
std::stringstream fileName;
|
||||
fileName << "outcomes-" << start << "-" << end << ".csv";
|
||||
std::ofstream MyFile(fileName.str());
|
||||
for (int i = 0; i < outcomes.size(); i++) {
|
||||
MyFile << "(" << outcomes[i][0] << "," << outcomes[i][1] << "," << threadCount << ")";
|
||||
}
|
||||
MyFile.close();
|
||||
}
|
||||
|
||||
int main() {
|
||||
int range_start = 100;
|
||||
int range_end = 1'000'000;
|
||||
int countThreads[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64};
|
||||
// int num_threads = std::thread::hardware_concurrency(); // use system's core
|
||||
// count
|
||||
for (int j = 0; j < (sizeof(countThreads) / sizeof(int)); j++) {
|
||||
int total = range_end - range_start;
|
||||
int chunk_size = total / countThreads[j];
|
||||
|
||||
std::vector<std::thread> threads;
|
||||
|
||||
for (int i = 1; i < countThreads[j]; ++i) {
|
||||
int start = range_start + i * chunk_size;
|
||||
int end = (i == countThreads[j] - 1) ? range_end : start + chunk_size;
|
||||
|
||||
threads.emplace_back(workerThread, start, end, countThreads[j]);
|
||||
}
|
||||
workerThread(range_start, range_end, countThreads[j]);
|
||||
|
||||
for (auto& t : threads)
|
||||
t.join();
|
||||
|
||||
std::cout << "All threads finished.\n";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user