diff --git a/.githooks/install b/.githooks/install new file mode 100755 index 000000000..5c084603f --- /dev/null +++ b/.githooks/install @@ -0,0 +1,14 @@ +#!/bin/sh + +cd "$(git rev-parse --git-dir)" +cd hooks + +echo "Installing hooks..." +# Install pre-commit hook if dependencies are satisfied +if ! [ -x "$(command -v git-clang-format)" ]; then + echo 'Error: pre-commit hook depends on git-clang-format, but is not installed.' >&2 + exit 1 +else + ln -s ../../.githooks/pre-commit pre-commit +fi +echo "Done!" diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 000000000..e6995993c --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,31 @@ +#!/bin/sh + +# Redirect output to stderr. +exec 1>&2 + +check_failed=false + +# Do the code format check +if ! "$(git rev-parse --show-toplevel)/Scripts/CodeFormat/check_format.sh" HEAD --cached 1>&2; then + printf "\n\033[31mFailed\033[0m: code format check.\n" + check_failed=true +fi + +# Do the copyright check +# update & apply copyright when hook config is set, otherwise just verify +opts="-qc" +if [ "$(git config --get --type bool --default false hooks.updateCopyright)" = "true" ]; then + opts="-qca" +fi + +if ! "$(git rev-parse --show-toplevel)/Scripts/CopyrightDate/check_copyright.sh" "$opts" 1>&2; then + printf "\n\033[31mFailed\033[0m: copyright date check.\n" + check_failed=true +fi + +if $check_failed; then + printf " +Pre-commit check failed, please fix the reported errors. +Note: Use '\033[33mgit commit --no-verify\033[0m' to bypass checks.\n" + exit 1 +fi diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 047562c23..4931f7ee8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -48,7 +48,7 @@ clang-format: stage: lint needs: [] tags: - - rocm-build + - build variables: CLANG_FORMAT: "/opt/rocm/llvm/bin/clang-format" GIT_CLANG_FORMAT: "/opt/rocm/llvm/bin/git-clang-format" @@ -59,6 +59,19 @@ clang-format: - git config --global --add safe.directory $CI_PROJECT_DIR - Scripts/CodeFormat/check_format.sh $CI_MERGE_REQUEST_DIFF_BASE_SHA --binary "$CLANG_FORMAT" +copyright-date: + image: $DOCKER_TAG_PREFIX:rocm-ubuntu + stage: lint + needs: [] + tags: + - build + rules: + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' + script: + - cd $CI_PROJECT_DIR + - git config --global --add safe.directory $CI_PROJECT_DIR + - Scripts/CopyrightDate/check_copyright.sh -v -d $CI_MERGE_REQUEST_DIFF_BASE_SHA + .build:dockerfiles: timeout: 60m image: @@ -67,7 +80,7 @@ clang-format: stage: build needs: [] tags: - - rocm-build + - build script: - mkdir -p /kaniko/.docker - echo "${DOCKER_AUTH_CONFIG}" > /kaniko/.docker/config.json @@ -108,7 +121,7 @@ build:make-rocm: extends: - .rules:build tags: - - rocm-build + - build needs: [] script: - cd $CI_PROJECT_DIR && make CXXFLAGS="$HIP_FLAGS" -j $(nproc) @@ -119,7 +132,7 @@ build:make-cuda: extends: - .rules:build tags: - - nvcc-build + - build needs: [] script: - cd $CI_PROJECT_DIR && make CXXFLAGS="$CUDA_FLAGS" GPU_RUNTIME=CUDA -j $(nproc) @@ -143,7 +156,7 @@ build:cmake-rocm: - .build:cmake - .gpus:rocm-gpus tags: - - rocm-build + - build script: - cmake -S $CI_PROJECT_DIR @@ -166,7 +179,7 @@ build:cmake-cuda: extends: - .build:cmake tags: - - nvcc-build + - build script: - cmake -S $CI_PROJECT_DIR @@ -209,6 +222,10 @@ test:cuda: extends: - .test - .gpus:nvcc + before_script: + - export HIP_COMPILER=nvcc + - export HIP_PLATFORM=nvidia + - export HIP_RUNTIME=cuda needs: - build:cmake-cuda diff --git a/Applications/bitonic_sort/main.hip b/Applications/bitonic_sort/main.hip index 31cd3e4c7..702928895 100644 --- a/Applications/bitonic_sort/main.hip +++ b/Applications/bitonic_sort/main.hip @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2023-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -148,7 +148,7 @@ int main(int argc, char* argv[]) { std::cout << "The ordering must be 'dec' or 'inc', the default ordering is 'inc'." << std::endl; - return 0; + return error_exit_code; } const bool sort_increasing = (sort.compare("inc") == 0); diff --git a/Applications/monte_carlo_pi/main.hip b/Applications/monte_carlo_pi/main.hip index 29004f8bf..8e4ee5d95 100644 --- a/Applications/monte_carlo_pi/main.hip +++ b/Applications/monte_carlo_pi/main.hip @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2023-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -126,7 +126,7 @@ int main(int argc, char* argv[]) if(sample_count <= 0) { std::cerr << "Sample count should be greater than 0." << std::endl; - return 0; + return error_exit_code; } // The samples have two dimensions, so two random numbers are required per sample. diff --git a/Applications/prefix_sum/main.hip b/Applications/prefix_sum/main.hip index 3be8a8965..469be5f46 100644 --- a/Applications/prefix_sum/main.hip +++ b/Applications/prefix_sum/main.hip @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2023-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -182,7 +182,7 @@ int main(int argc, char* argv[]) if(size <= 0) { std::cout << "Size must be at least 1." << std::endl; - exit(0); + return error_exit_code; } // 2. Generate input vector. diff --git a/Common/hipsolver_utils.hpp b/Common/hipsolver_utils.hpp index b672303ca..bb3ef157e 100644 --- a/Common/hipsolver_utils.hpp +++ b/Common/hipsolver_utils.hpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2023-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -52,10 +52,10 @@ inline const char* hipsolverStatusToString(hipsolverStatus_t status) #if (hipsolverVersionMajor >= 2 && hipsolverVersionMinor >= 1) case HIPSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED : return "HIPSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED"; #endif + // We do use default because we are not in control of these enumeration values. + // Ideally this function is something hipsolver would provide + default: return ""; } - // We don't use default so that the compiler warns if any valid enums are missing from the - // switch. If the value is not a valid hipsolverStatus_t, we return the following. - return ""; } /// \brief Checks if the provided status code is \p HIPSOLVER_STATUS_SUCCESS and if not, diff --git a/Common/rocsparse_utils.hpp b/Common/rocsparse_utils.hpp index 68303f879..5935152de 100644 --- a/Common/rocsparse_utils.hpp +++ b/Common/rocsparse_utils.hpp @@ -53,10 +53,10 @@ inline const char* rocsparse_status_to_string(rocsparse_status status) #endif case rocsparse_status_requires_sorted_storage: return "rocsparse_status_requires_sorted_storage"; + // We do use default because we are not in control of these enumeration values. + // Ideally this function is something rocsparse would provide + default: return ""; } - // We don't use default so that the compiler warns if any valid enums are missing from the - // switch. If the value is not a valid rocsparse_status, we return the following. - return ""; } /// \brief Checks if the provided status code is \p rocsparse_status_success and if not, diff --git a/HIP-Basic/CMakeLists.txt b/HIP-Basic/CMakeLists.txt index 860c1102a..02f1f0eb8 100644 --- a/HIP-Basic/CMakeLists.txt +++ b/HIP-Basic/CMakeLists.txt @@ -95,6 +95,10 @@ if(NOT WIN32) message("Perl not found, not building hipify example") endif() endif() +if("${GPU_RUNTIME}" STREQUAL "CUDA") + add_subdirectory(hello_world_cuda) +endif() + add_subdirectory(inline_assembly) add_subdirectory(matrix_multiplication) add_subdirectory(moving_average) diff --git a/HIP-Basic/hello_world_cuda/CMakeLists.txt b/HIP-Basic/hello_world_cuda/CMakeLists.txt new file mode 100644 index 000000000..36b696cf2 --- /dev/null +++ b/HIP-Basic/hello_world_cuda/CMakeLists.txt @@ -0,0 +1,51 @@ +# MIT License +# +# Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +set(example_name hip_hello_world_cuda) + +cmake_minimum_required(VERSION 3.21 FATAL_ERROR) + +# CMake's HIP language mode does not yet support compiling with CUDA, thereby we must +# resort to the CUDA language mode. +project(${example_name} LANGUAGES CUDA) + +if(WIN32) + set(ROCM_ROOT "$ENV{HIP_PATH}" CACHE PATH "Root directory of the ROCm installation") +else() + set(ROCM_ROOT "/opt/rocm" CACHE PATH "Root directory of the ROCm installation") +endif() + +add_executable(${example_name} main.hip) + +# Make example runnable using ctest +add_test(${example_name} ${example_name}) + +# Make the HIP runtime headers accessible +target_include_directories(${example_name} PRIVATE + "${ROCM_ROOT}/include" + "${CMAKE_CURRENT_SOURCE_DIR}/../../Common") + +# Set up the compilation language for the source file. +# Usually this can be deduced from the file extension, but not in the case of .hip. +set_source_files_properties(main.hip PROPERTIES LANGUAGE CUDA) + +install(TARGETS ${example_name}) diff --git a/HIP-Basic/hello_world_cuda/README.md b/HIP-Basic/hello_world_cuda/README.md new file mode 100644 index 000000000..e96a0ce8c --- /dev/null +++ b/HIP-Basic/hello_world_cuda/README.md @@ -0,0 +1,31 @@ +# HIP-Basic Hello World on the CUDA platform Example + +## Description + +This example showcases a simple HIP program that is compiled on the CUDA platform using CMake. + +### Application flow + +1. A kernel is launched: the function `hello_world_kernel` is executed on the device. The kernel is executed on a single thread, and prints "Hello, World!" to the console. +2. A launch error check is performed using `hipGetLastError`. +3. _Synchronization_ is performed: the host program execution halts until the kernel on the device has finished executing. + +## Key APIs and Concepts + +- For introduction to the programming concepts in this example, refer to the general [hello world example](../hello_world/). +- This example showcases setting up a HIP program to be compiled to the CUDA platform using CMake. + - Since CMake (as of version 3.21) does not support compiling to CUDA in HIP language mode, CUDA language mode has to be used. Thereby the project language is specified as `CUDA`. + - Additionally, we must "teach" CMake to compile the source file `main.hip` in CUDA language mode, because it cannot guess that from the file extension. This is done by `set_source_files_properties(main.hip PROPERTIES LANGUAGE CUDA)`. + - The HIP "runtime" on the CUDA platform is header only. Thereby there is no need to link to a library, but the HIP include directory have to be added to the search paths. This is performed by `target_include_directories(${example_name} PRIVATE "${ROCM_ROOT}/include"`. + +## Demonstrated API Calls + +### HIP Runtime + +- `hipGetLastError` +- `hipDeviceSynchronize` +- `__global__` + +## Supported Platforms + +This example is only supported on the CUDA platform. diff --git a/HIP-Basic/hello_world_cuda/main.hip b/HIP-Basic/hello_world_cuda/main.hip new file mode 100644 index 000000000..a606032b7 --- /dev/null +++ b/HIP-Basic/hello_world_cuda/main.hip @@ -0,0 +1,39 @@ +// MIT License +// +// Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include + +#include "example_utils.hpp" + +__global__ void hello_world_kernel() +{ + printf("Hello, World!\n"); +} + +int main() +{ + static constexpr unsigned int grid_size = 1; + static constexpr unsigned int block_size = 1; + hello_world_kernel<<>>(); + HIP_CHECK(hipGetLastError()); + HIP_CHECK(hipDeviceSynchronize()); +} diff --git a/Libraries/hipBLAS/gemm_strided_batched/main.hip b/Libraries/hipBLAS/gemm_strided_batched/main.hip index 95b2d0d53..456d40cde 100644 --- a/Libraries/hipBLAS/gemm_strided_batched/main.hip +++ b/Libraries/hipBLAS/gemm_strided_batched/main.hip @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2022-204 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -59,25 +59,25 @@ int main(const int argc, const char** argv) if(m <= 0) { std::cout << "Value of 'm' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } if(n <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } if(k <= 0) { std::cout << "Value of 'k' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } if(batch_count <= 0) { std::cout << "Value of 'c' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Set scalar values used for multiplication. diff --git a/Libraries/hipBLAS/her/main.hip b/Libraries/hipBLAS/her/main.hip index 4f1b43fbf..b0cc5866c 100644 --- a/Libraries/hipBLAS/her/main.hip +++ b/Libraries/hipBLAS/her/main.hip @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2022-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -77,15 +77,15 @@ int main(const int argc, const char** argv) if(incx <= 0) { std::cout << "Value of 'x' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Increment between consecutive values of the input vector y. const int incy = parser.get("y"); - if(incx <= 0) + if(incy <= 0) { std::cout << "Value of 'y' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Number of elements in the input vectors and dimension of input matrix. @@ -93,7 +93,7 @@ int main(const int argc, const char** argv) if(n <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Scalar multiplier. diff --git a/Libraries/hipBLAS/scal/main.hip b/Libraries/hipBLAS/scal/main.hip index 9b3060aa3..0420637de 100644 --- a/Libraries/hipBLAS/scal/main.hip +++ b/Libraries/hipBLAS/scal/main.hip @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2022-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -49,7 +49,7 @@ int main(const int argc, const char** argv) if(incx <= 0) { std::cout << "Value of 'x' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Number of elements in input vector. @@ -57,7 +57,7 @@ int main(const int argc, const char** argv) if(n <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Scalar value used for multiplication. diff --git a/Libraries/hipSOLVER/gels/main.cpp b/Libraries/hipSOLVER/gels/main.cpp index acda069d6..dc8597c39 100644 --- a/Libraries/hipSOLVER/gels/main.cpp +++ b/Libraries/hipSOLVER/gels/main.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2023-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -45,14 +45,14 @@ int main(const int argc, char* argv[]) if(m <= 0) { std::cout << "Value of 'm' should be greater than 0." << std::endl; - return 0; + return error_exit_code; } const int n = parser.get("n"); if(n <= 0) { std::cout << "Value of 'n' should be greater than 0." << std::endl; - return 0; + return error_exit_code; } // Initialize leading dimensions of the input- and output matrices, diff --git a/Libraries/hipSOLVER/gesvd/main.cpp b/Libraries/hipSOLVER/gesvd/main.cpp index 6ad899f52..7c17503e8 100644 --- a/Libraries/hipSOLVER/gesvd/main.cpp +++ b/Libraries/hipSOLVER/gesvd/main.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2023-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -49,14 +49,14 @@ int main(const int argc, char* argv[]) if(m <= 0) { std::cout << "Value of 'm' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } const int n = parser.get("n"); if(n <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Initialize leading dimensions of input matrix A and output singular vector matrices. diff --git a/Libraries/hipSOLVER/getrf/main.cpp b/Libraries/hipSOLVER/getrf/main.cpp index 687c5ab79..43616241d 100644 --- a/Libraries/hipSOLVER/getrf/main.cpp +++ b/Libraries/hipSOLVER/getrf/main.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2023-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -47,14 +47,14 @@ int main(const int argc, const char* argv[]) if(m <= 0) { std::cout << "Value of 'm' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } const int n = parser.get("n"); if(n <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Initialize leading dimensions of input matrix A and output matrix LU. diff --git a/Libraries/hipSOLVER/syevj/main.cpp b/Libraries/hipSOLVER/syevj/main.cpp index e1afd94aa..e08687057 100644 --- a/Libraries/hipSOLVER/syevj/main.cpp +++ b/Libraries/hipSOLVER/syevj/main.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2023-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -43,7 +43,7 @@ int main(const int argc, char* argv[]) if(n <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } const int lda = n; diff --git a/Libraries/hipSOLVER/syevj_batched/main.cpp b/Libraries/hipSOLVER/syevj_batched/main.cpp index 03116a07e..56f1128e2 100644 --- a/Libraries/hipSOLVER/syevj_batched/main.cpp +++ b/Libraries/hipSOLVER/syevj_batched/main.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2023-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -48,7 +48,7 @@ int main(const int argc, char* argv[]) if(n <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } const int lda = n; const int size_matrix = n * lda; @@ -58,7 +58,7 @@ int main(const int argc, char* argv[]) if(batch_count <= 0) { std::cout << "Batch size should be at least 1" << std::endl; - return 0; + return error_exit_code; } // 2. Allocate and initialize the host side inputs. diff --git a/Libraries/rocBLAS/level_1/axpy/main.cpp b/Libraries/rocBLAS/level_1/axpy/main.cpp index f4a0f06c1..481d57698 100644 --- a/Libraries/rocBLAS/level_1/axpy/main.cpp +++ b/Libraries/rocBLAS/level_1/axpy/main.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2022-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -49,7 +49,7 @@ int main(const int argc, const char** argv) if(incx <= 0) { std::cout << "Value of 'x' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Stride between consecutive values of input vector y. @@ -57,7 +57,7 @@ int main(const int argc, const char** argv) if(incy <= 0) { std::cout << "Value of 'y' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Number of elements in input vector x and input vector y. @@ -65,7 +65,7 @@ int main(const int argc, const char** argv) if(n <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Scalar value used for multiplication. diff --git a/Libraries/rocBLAS/level_1/dot/main.cpp b/Libraries/rocBLAS/level_1/dot/main.cpp index 1449e7ea5..1d413874a 100644 --- a/Libraries/rocBLAS/level_1/dot/main.cpp +++ b/Libraries/rocBLAS/level_1/dot/main.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2022-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -56,19 +56,19 @@ int main(const int argc, const char** argv) if(incx <= 0) { std::cout << "Value of 'x' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } if(incy <= 0) { std::cout << "Value of 'y' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } if(n <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Adjust the size of input vector x for values of stride (incx) not equal to 1. diff --git a/Libraries/rocBLAS/level_1/nrm2/main.cpp b/Libraries/rocBLAS/level_1/nrm2/main.cpp index f12d0a7e8..2c06d740e 100644 --- a/Libraries/rocBLAS/level_1/nrm2/main.cpp +++ b/Libraries/rocBLAS/level_1/nrm2/main.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2022-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -67,13 +67,13 @@ int main(const int argc, const char** argv) if(incx <= 0) { std::cout << "Value of 'x' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } if(n <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Adjust the size of input vector for values of stride (incx) not equal to 1. diff --git a/Libraries/rocBLAS/level_1/scal/main.cpp b/Libraries/rocBLAS/level_1/scal/main.cpp index 69e231d30..010a4592a 100644 --- a/Libraries/rocBLAS/level_1/scal/main.cpp +++ b/Libraries/rocBLAS/level_1/scal/main.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2022-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -49,7 +49,7 @@ int main(const int argc, const char** argv) if(incx <= 0) { std::cout << "Value of 'x' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Number of elements in input vector. @@ -57,7 +57,7 @@ int main(const int argc, const char** argv) if(n <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Scalar value used for multiplication. diff --git a/Libraries/rocBLAS/level_2/gemv/main.cpp b/Libraries/rocBLAS/level_2/gemv/main.cpp index 0130725d3..ed9f27dcb 100644 --- a/Libraries/rocBLAS/level_2/gemv/main.cpp +++ b/Libraries/rocBLAS/level_2/gemv/main.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2022-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -108,7 +108,7 @@ int main(const int argc, const char** argv) if(cols <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Number of rows in the matrix. @@ -116,7 +116,7 @@ int main(const int argc, const char** argv) if(rows <= 0) { std::cout << "Value of 'm' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Alpha scalar multiplier. diff --git a/Libraries/rocBLAS/level_2/her/main.cpp b/Libraries/rocBLAS/level_2/her/main.cpp index 076da7e7b..34bfe5457 100644 --- a/Libraries/rocBLAS/level_2/her/main.cpp +++ b/Libraries/rocBLAS/level_2/her/main.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2022-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -79,7 +79,7 @@ int main(const int argc, const char** argv) if(n <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Scalar multiplier. diff --git a/Libraries/rocBLAS/level_3/gemm/main.cpp b/Libraries/rocBLAS/level_3/gemm/main.cpp index 8190a7b87..f4c9ad4cb 100644 --- a/Libraries/rocBLAS/level_3/gemm/main.cpp +++ b/Libraries/rocBLAS/level_3/gemm/main.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2022-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -54,19 +54,19 @@ int main(const int argc, const char** argv) if(m <= 0) { std::cout << "Value of 'm' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } if(n <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } if(k <= 0) { std::cout << "Value of 'k' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Set scalar values used for multiplication. diff --git a/Libraries/rocBLAS/level_3/gemm_strided_batched/main.cpp b/Libraries/rocBLAS/level_3/gemm_strided_batched/main.cpp index 471df167b..469875ed7 100644 --- a/Libraries/rocBLAS/level_3/gemm_strided_batched/main.cpp +++ b/Libraries/rocBLAS/level_3/gemm_strided_batched/main.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2022-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -59,25 +59,25 @@ int main(const int argc, const char** argv) if(m <= 0) { std::cout << "Value of 'm' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } if(n <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } if(k <= 0) { std::cout << "Value of 'k' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } if(batch_count <= 0) { std::cout << "Value of 'c' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Set scalar values used for multiplication. diff --git a/Libraries/rocSOLVER/getf2/main.cpp b/Libraries/rocSOLVER/getf2/main.cpp index 1b4a33631..866ab856a 100644 --- a/Libraries/rocSOLVER/getf2/main.cpp +++ b/Libraries/rocSOLVER/getf2/main.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2023-2024 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -48,14 +48,14 @@ int main(const int argc, const char* argv[]) if(m <= 0) { std::cout << "Value of 'm' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } const rocblas_int n = parser.get("n"); if(n <= 0) { std::cout << "Value of 'n' should be greater than 0" << std::endl; - return 0; + return error_exit_code; } // Initialize leading dimensions of input matrix A and output matrix LU. diff --git a/README.md b/README.md index f68687dd0..d1e61e1b6 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ A collection of examples to enable new users to start using ROCm. Advanced users - [events](https://github.com/ROCm/rocm-examples/tree/develop/HIP-Basic/events/): Measuring execution time and synchronizing with HIP events. - [gpu_arch](https://github.com/ROCm/rocm-examples/tree/develop/HIP-Basic/gpu_arch/): Program that showcases how to implement GPU architecture-specific code. - [hello_world](https://github.com/ROCm/rocm-examples/tree/develop/HIP-Basic/hello_world): Simple program that showcases launching kernels and printing from the device. + - [hello_world_cuda](https://github.com/ROCm/rocm-examples/tree/develop/HIP-Basic/hello_world_cuda): Simple HIP program that showcases setting up CMake to target the CUDA platform. - [hipify](https://github.com/ROCm/rocm-examples/tree/develop/HIP-Basic/hipify): Simple program and build definitions that showcase automatically converting a CUDA `.cu` source into portable HIP `.hip` source. - [llvm_ir_to_executable](https://github.com/ROCm/rocm-examples/tree/develop/HIP-Basic/llvm_ir_to_executable): Shows how to create a HIP executable from LLVM IR. - [inline_assembly](https://github.com/ROCm/rocm-examples/tree/develop/HIP-Basic/inline_assembly/): Program that showcases how to use inline assembly in a portable manner. diff --git a/Scripts/CopyrightDate/check_copyright.sh b/Scripts/CopyrightDate/check_copyright.sh new file mode 100755 index 000000000..04d941b96 --- /dev/null +++ b/Scripts/CopyrightDate/check_copyright.sh @@ -0,0 +1,222 @@ +#!/usr/bin/env bash + +# Start of configuration +preamble="Copyright +(\([cC]\) +)?" +postamble=",? +Advanced +Micro +Devices, +Inc\." +find_pattern="$preamble([0-9]{4}-)?[0-9]{4}$postamble" +# printf format string, receives the current year as a parameter +uptodate_pattern="$preamble([0-9]{4}-)?%d$postamble" +# / interpreted with sed syntax, also passed to printf +# printf interprets '\' escape sequences so they must be escaped +# The capture groups are as follows: +# - \1 is the whole preamble text +# - \3 is the start year, \2 is skipped because it is used for an optional part of the preamble +# - \5 is the end of the copyright statement after the end year, \4 would be the original end year +# as written in the file, it is replaced by the current year instead. +replace_pattern="($preamble)([0-9]{4})(-[0-9]{4})?($postamble)/\\\1\\\3-%d\\\5" +# End of configuration + +print_help() { printf -- \ +"\033[36musuage\033[0m: \033[33mcheck_year.sh [-h] [-u] [-a] [-d ] [-k] [-v]\033[0m +\033[36mdescription\033[0m: Checks for if the copyright year in the staged files is up to date and displays the files with out-of-date copyright statements. Exits with '0' if successful and with '1' if something is out of date. +\033[36moptions\033[0m: + \033[34m-h\033[0m Displays this message. + \033[34m-u\033[0m Automatically updates the copyright year + \033[34m-a\033[0m Automatically applies applies the changes to current staging environment. Implies '-u' and '-c'. + \033[34m-c\033[0m Compare files to the index instead of the working tree. + \033[34m-d \033[0m Compare using the diff of a hash. + \033[34m-k\033[0m Compare using the fork point: where this branch and 'remotes/origin/HEAD' diverge. + \033[34m-q\033[0m Suppress updates about progress. + \033[34m-v\033[0m Verbose output. +Use '\033[33mgit config --local hooks.updateCopyright \033[0m' to automatically apply copyright changes on commit. +" +} + +# argument parsing +apply=false +update=false +verbose=false +forkdiff=false +quiet=false +cached=false + +while getopts "auhvkqcd:" arg; do + case $arg in + a) update=true;apply=true;cached=true;; + u) update=true;; + v) verbose=true;; + k) forkdiff=true;; + q) quiet=true;; + c) cached=true;; + d) diff_hash=${OPTARG};; + h) print_help; exit;; + *) print help; exit 1;; + esac +done + +# If set, check all files changed since the fork point +if $forkdiff; then + branch="$(git rev-parse --abbrev-ref HEAD)" + remote="$(git config --local --get "branch.$branch.remote" || echo 'origin')" + source_commit="remotes/$remote/HEAD" + + # don't use fork-point for finding fork point (lol) + # see: https://stackoverflow.com/a/53981615 + diff_hash="$(git merge-base "$source_commit" "$branch")" +fi + +if [ -n "${diff_hash}" ]; then + $verbose && printf -- "Using base commit: %s\n" "${diff_hash}" +else + diff_hash="HEAD" +fi + +# Current year +year="$(date +%Y)" + +# Enable rename detection with full matches only, this skips copyright checks for file name only +# changes. +diff_opts=(-z --name-only '--diff-filter=MA' '--find-renames=100%') +git_grep_opts=(-z --extended-regexp --ignore-case --no-recursive -I) +if $cached; then + diff_opts+=(--cached) + git_grep_opts+=(--cached) +fi + +! $quiet && printf -- "Checking if copyright statements are up-to-date... " +mapfile -d $'\0' changed_files < <(git diff-index "${diff_opts[@]}" "$diff_hash" | LANG=C.UTF-8 sort -z) + +if ! (( ${#changed_files[@]} )); then + ! $quiet && printf -- "\033[32mDone!\033[0m\n" + $verbose && printf -- "\033[36mNo changed files found.\033[0m\n" + exit 0 +fi; + +mapfile -d $'\0' found_copyright < <( \ + git grep "${git_grep_opts[@]}" --files-with-matches -e "$find_pattern" \ + -- "${changed_files[@]}" | \ + LANG=C.UTF-8 sort -z) + +outdated_copyright=() +if (( ${#found_copyright[@]} )); then + # uptodate_pattern variable holds the format string using it as such is intentional + # shellcheck disable=SC2059 + printf -v uptodate_pattern -- "$uptodate_pattern" "$year" + mapfile -d $'\0' outdated_copyright < <( \ + git grep "${git_grep_opts[@]}" --files-without-match -e "$uptodate_pattern" \ + -- "${found_copyright[@]}" | \ + LANG=C.UTF-8 sort -z) +fi + +! $quiet && printf -- "\033[32mDone!\033[0m\n" +if $verbose; then + # Compute the files that don't have a copyright as the set difference of + # `changed_files and `found_copyright` + mapfile -d $'\0' notfound_copyright < <( \ + printf -- '%s\0' "${changed_files[@]}" | \ + LANG=C.UTF-8 comm -z -23 - <(printf -- '%s\0' "${found_copyright[@]}")) + + if (( ${#notfound_copyright[@]} )); then + printf -- "\033[36mCouldn't find a copyright statement in %d file(s):\033[0m\n" \ + "${#notfound_copyright[@]}" + printf -- ' - %q\n' "${notfound_copyright[@]}" + fi + + # Similarly the up-to-date files are the difference of `found_copyright` and `outdated_copyright` + mapfile -d $'\0' uptodate_copyright < <( \ + printf -- '%s\0' "${found_copyright[@]}" | \ + LANG=C.UTF-8 comm -z -23 - <(printf -- '%s\0' "${outdated_copyright[@]}")) + + if (( ${#uptodate_copyright[@]} )); then + printf -- "\033[36mThe copyright statement was already up to date in %d file(s):\033[0m\n" \ + "${#uptodate_copyright[@]}" + printf -- ' - %q\n' "${uptodate_copyright[@]}" + fi +fi + +if ! (( ${#outdated_copyright[@]} )); then + exit 0 +fi + +printf -- \ +"\033[31m==== COPYRIGHT OUT OF DATE ====\033[0m +\033[36m%d file(s) need(s) to be updated:\033[0m\n" "${#outdated_copyright[@]}" +printf -- ' - %q\n' "${outdated_copyright[@]}" + +# If we don't need to update, we early exit. +if ! $update; then + printf -- \ +"\nRun '\033[33mscripts/copyright-date/check-copyright.sh -u\033[0m' to update the copyright statement(s). See '-h' for more info, +or set '\033[33mgit config --local hooks.updateCopyright true\033[0m' to automatically update copyrights when committing.\n" + exit 1 +fi + +if $apply; then + ! $quiet && printf -- "Updating copyrights and staging changes... " +else + ! $quiet && printf -- "Updating copyrights... " +fi + +# replace_pattern variable holds a format string, using it as such is intentional +# shellcheck disable=SC2059 +printf -v replace_pattern -- "$replace_pattern" "$year" +# Just update the files in place if only touching the working-tree +if ! $apply; then + sed --regexp-extended --separate "s/$replace_pattern/g" -i "${outdated_copyright[@]}" + printf -- "\033[32mDone!\033[0m\n" + exit 0 +fi + +generate_patch() { + # Sed command to create a hunk for a copyright statement fix + # expects input to be line number then copyright statement on the next line + to_hunk_cmd="{# Print hunk header, move to the next line + s/.+/@@ -&,1 +&,1 @@/;n + # Print removed line by prepending '-' to it + ;s/^/-/;p + # Print added line, replace the '-' with '+' and replace the copyright statement + s/^-/+/;s/$replace_pattern/g}" + + # Run file-names through git ls-files, just to get a (possibly) quoted name for each + mapfile -t -d $'\n' quoted_files < <(git ls-files --cached -- "${outdated_copyright[@]}") + for ((i = 0;i < ${#outdated_copyright[@]}; i++)); do + file="${outdated_copyright["$i"]}" + quoted="${quoted_files["$i"]}" + # Drop the quote from the start and end (to avoid quoting twice) + escaped="${quoted#\"}"; escaped="${escaped%\"}" + a="\"a/$escaped\"" + b="\"b/$escaped\"" + + printf -- "diff --git %s %s\n--- %s\n+++ %s\n" "$a" "$b" "$a" "$b" + + # Print line number and line for each line with a copyright statement + git cat-file blob ":$file" | \ + sed --quiet --regexp-extended "/$find_pattern/{=;p}" | \ + sed --regexp-extended "$to_hunk_cmd" + done +} + +patch_file="$(git rev-parse --git-dir)/copyright-fix.patch" +generate_patch > "$patch_file" + +# Cleanup patch file when the script exits +finish () { + rm -f "$patch_file" +} +# The trap will be invoked whenever the script exits, even due to a signal, this is a bash only +# feature +trap finish EXIT + +if ! git apply --unidiff-zero < "$patch_file"; then + printf -- "\033[31mFailed to apply changes to working tree. +Perhaps the fix is already applied, but not yet staged?\n\033[0m" + exit 1 +fi + +if ! git apply --cached --unidiff-zero < "$patch_file"; then + printf -- "\033[31mFailed to apply change to the index.\n\033[0m" + exit 1 +fi + +! $quiet && printf -- "\033[32mDone!\033[0m\n" +exit 0