From 632a7a44b60643b3afc617a48dd221f9f49c7d17 Mon Sep 17 00:00:00 2001 From: Joseph Oster Date: Wed, 12 Aug 2020 16:06:58 -0700 Subject: [PATCH 001/121] Updating License file to no date in the title /* * Copyright (c) 2020 Intel Corporation * * This program and the accompanying materials are made available under the * terms of the The MIT License which is available at * https://opensource.org/licenses/MIT. * * SPDX-License-Identifier: MIT */ --- .../C++/CombinationalLogic/MandelbrotOMP/license.txt | 2 +- .../C++/CompilerInfrastructure/Intrinsics/license.txt | 2 +- DirectProgramming/C++/GraphTraversal/MergesortOMP/license.txt | 2 +- .../DPC++/CombinationalLogic/mandelbrot/License.txt | 2 +- .../DPC++/CombinationalLogic/sepia-filter/License.txt | 2 +- .../DPC++/DenseLinearAlgebra/complex_mult/License.txt | 2 +- .../DPC++/DenseLinearAlgebra/matrix_mul/License.txt | 2 +- .../DPC++/DenseLinearAlgebra/simple-add/License.txt | 2 +- .../DPC++/DenseLinearAlgebra/vector-add/License.txt | 2 +- DirectProgramming/DPC++/GraphTraversal/bitonic-sort/License.txt | 2 +- .../DPC++/SpectralMethods/DiscreteCosineTransform/license.txt | 2 +- .../DPC++/StructuredGrids/1d_HeatTransfer/License.txt | 2 +- .../DPC++/StructuredGrids/iso2dfd_dpcpp/License.txt | 2 +- .../DPC++/StructuredGrids/iso3dfd_dpcpp/License.txt | 2 +- .../DPC++/StructuredGrids/particle-diffusion/License.txt | 2 +- DirectProgramming/Fortran/openmp_samples/License.txt | 2 +- DirectProgramming/Fortran/optimize_samples/License.txt | 2 +- DirectProgramming/Fortran/vec_samples/License.txt | 2 +- Libraries/oneDPL/gamma-correction/License.txt | 2 +- Libraries/oneDPL/stable_sort_by_key/License.txt | 2 +- License.txt | 2 +- Tools/SystemDebug/system_debug_sample/License.txt | 2 +- Tools/SystemDebug/system_debug_sample_build/License.txt | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/DirectProgramming/C++/CombinationalLogic/MandelbrotOMP/license.txt b/DirectProgramming/C++/CombinationalLogic/MandelbrotOMP/license.txt index 65315c87a4..9cde07f558 100644 --- a/DirectProgramming/C++/CombinationalLogic/MandelbrotOMP/license.txt +++ b/DirectProgramming/C++/CombinationalLogic/MandelbrotOMP/license.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/C++/CompilerInfrastructure/Intrinsics/license.txt b/DirectProgramming/C++/CompilerInfrastructure/Intrinsics/license.txt index 65315c87a4..9cde07f558 100644 --- a/DirectProgramming/C++/CompilerInfrastructure/Intrinsics/license.txt +++ b/DirectProgramming/C++/CompilerInfrastructure/Intrinsics/license.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/C++/GraphTraversal/MergesortOMP/license.txt b/DirectProgramming/C++/GraphTraversal/MergesortOMP/license.txt index 65315c87a4..9cde07f558 100644 --- a/DirectProgramming/C++/GraphTraversal/MergesortOMP/license.txt +++ b/DirectProgramming/C++/GraphTraversal/MergesortOMP/license.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/DPC++/CombinationalLogic/mandelbrot/License.txt b/DirectProgramming/DPC++/CombinationalLogic/mandelbrot/License.txt index 8f608e972a..9cde07f558 100644 --- a/DirectProgramming/DPC++/CombinationalLogic/mandelbrot/License.txt +++ b/DirectProgramming/DPC++/CombinationalLogic/mandelbrot/License.txt @@ -1,4 +1,4 @@ -Copyright 2019 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/DPC++/CombinationalLogic/sepia-filter/License.txt b/DirectProgramming/DPC++/CombinationalLogic/sepia-filter/License.txt index da5f7c1888..e63c6e13dc 100644 --- a/DirectProgramming/DPC++/CombinationalLogic/sepia-filter/License.txt +++ b/DirectProgramming/DPC++/CombinationalLogic/sepia-filter/License.txt @@ -1,4 +1,4 @@ -Copyright 2019 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/DPC++/DenseLinearAlgebra/complex_mult/License.txt b/DirectProgramming/DPC++/DenseLinearAlgebra/complex_mult/License.txt index 65315c87a4..9cde07f558 100644 --- a/DirectProgramming/DPC++/DenseLinearAlgebra/complex_mult/License.txt +++ b/DirectProgramming/DPC++/DenseLinearAlgebra/complex_mult/License.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/DPC++/DenseLinearAlgebra/matrix_mul/License.txt b/DirectProgramming/DPC++/DenseLinearAlgebra/matrix_mul/License.txt index 65315c87a4..9cde07f558 100644 --- a/DirectProgramming/DPC++/DenseLinearAlgebra/matrix_mul/License.txt +++ b/DirectProgramming/DPC++/DenseLinearAlgebra/matrix_mul/License.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/DPC++/DenseLinearAlgebra/simple-add/License.txt b/DirectProgramming/DPC++/DenseLinearAlgebra/simple-add/License.txt index 65315c87a4..9cde07f558 100644 --- a/DirectProgramming/DPC++/DenseLinearAlgebra/simple-add/License.txt +++ b/DirectProgramming/DPC++/DenseLinearAlgebra/simple-add/License.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/DPC++/DenseLinearAlgebra/vector-add/License.txt b/DirectProgramming/DPC++/DenseLinearAlgebra/vector-add/License.txt index 8f608e972a..9cde07f558 100644 --- a/DirectProgramming/DPC++/DenseLinearAlgebra/vector-add/License.txt +++ b/DirectProgramming/DPC++/DenseLinearAlgebra/vector-add/License.txt @@ -1,4 +1,4 @@ -Copyright 2019 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/DPC++/GraphTraversal/bitonic-sort/License.txt b/DirectProgramming/DPC++/GraphTraversal/bitonic-sort/License.txt index 6e9524bd74..415025cf03 100644 --- a/DirectProgramming/DPC++/GraphTraversal/bitonic-sort/License.txt +++ b/DirectProgramming/DPC++/GraphTraversal/bitonic-sort/License.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/DPC++/SpectralMethods/DiscreteCosineTransform/license.txt b/DirectProgramming/DPC++/SpectralMethods/DiscreteCosineTransform/license.txt index 65315c87a4..9cde07f558 100644 --- a/DirectProgramming/DPC++/SpectralMethods/DiscreteCosineTransform/license.txt +++ b/DirectProgramming/DPC++/SpectralMethods/DiscreteCosineTransform/license.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/DPC++/StructuredGrids/1d_HeatTransfer/License.txt b/DirectProgramming/DPC++/StructuredGrids/1d_HeatTransfer/License.txt index 0578223382..415025cf03 100644 --- a/DirectProgramming/DPC++/StructuredGrids/1d_HeatTransfer/License.txt +++ b/DirectProgramming/DPC++/StructuredGrids/1d_HeatTransfer/License.txt @@ -1,4 +1,4 @@ -Copyright 2019 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/DPC++/StructuredGrids/iso2dfd_dpcpp/License.txt b/DirectProgramming/DPC++/StructuredGrids/iso2dfd_dpcpp/License.txt index 6e9524bd74..415025cf03 100644 --- a/DirectProgramming/DPC++/StructuredGrids/iso2dfd_dpcpp/License.txt +++ b/DirectProgramming/DPC++/StructuredGrids/iso2dfd_dpcpp/License.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/DPC++/StructuredGrids/iso3dfd_dpcpp/License.txt b/DirectProgramming/DPC++/StructuredGrids/iso3dfd_dpcpp/License.txt index 148940418d..e63c6e13dc 100644 --- a/DirectProgramming/DPC++/StructuredGrids/iso3dfd_dpcpp/License.txt +++ b/DirectProgramming/DPC++/StructuredGrids/iso3dfd_dpcpp/License.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/DPC++/StructuredGrids/particle-diffusion/License.txt b/DirectProgramming/DPC++/StructuredGrids/particle-diffusion/License.txt index 148940418d..e63c6e13dc 100644 --- a/DirectProgramming/DPC++/StructuredGrids/particle-diffusion/License.txt +++ b/DirectProgramming/DPC++/StructuredGrids/particle-diffusion/License.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/Fortran/openmp_samples/License.txt b/DirectProgramming/Fortran/openmp_samples/License.txt index 6e9524bd74..415025cf03 100644 --- a/DirectProgramming/Fortran/openmp_samples/License.txt +++ b/DirectProgramming/Fortran/openmp_samples/License.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/Fortran/optimize_samples/License.txt b/DirectProgramming/Fortran/optimize_samples/License.txt index 6e9524bd74..415025cf03 100644 --- a/DirectProgramming/Fortran/optimize_samples/License.txt +++ b/DirectProgramming/Fortran/optimize_samples/License.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: diff --git a/DirectProgramming/Fortran/vec_samples/License.txt b/DirectProgramming/Fortran/vec_samples/License.txt index 6e9524bd74..415025cf03 100644 --- a/DirectProgramming/Fortran/vec_samples/License.txt +++ b/DirectProgramming/Fortran/vec_samples/License.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: diff --git a/Libraries/oneDPL/gamma-correction/License.txt b/Libraries/oneDPL/gamma-correction/License.txt index 8f608e972a..9cde07f558 100644 --- a/Libraries/oneDPL/gamma-correction/License.txt +++ b/Libraries/oneDPL/gamma-correction/License.txt @@ -1,4 +1,4 @@ -Copyright 2019 Intel Corporation +Copyright Intel Corporation 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: diff --git a/Libraries/oneDPL/stable_sort_by_key/License.txt b/Libraries/oneDPL/stable_sort_by_key/License.txt index 8f608e972a..9cde07f558 100644 --- a/Libraries/oneDPL/stable_sort_by_key/License.txt +++ b/Libraries/oneDPL/stable_sort_by_key/License.txt @@ -1,4 +1,4 @@ -Copyright 2019 Intel Corporation +Copyright Intel Corporation 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: diff --git a/License.txt b/License.txt index da5f7c1888..e63c6e13dc 100644 --- a/License.txt +++ b/License.txt @@ -1,4 +1,4 @@ -Copyright 2019 Intel Corporation +Copyright Intel Corporation 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: diff --git a/Tools/SystemDebug/system_debug_sample/License.txt b/Tools/SystemDebug/system_debug_sample/License.txt index 65315c87a4..9cde07f558 100644 --- a/Tools/SystemDebug/system_debug_sample/License.txt +++ b/Tools/SystemDebug/system_debug_sample/License.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: diff --git a/Tools/SystemDebug/system_debug_sample_build/License.txt b/Tools/SystemDebug/system_debug_sample_build/License.txt index 65315c87a4..9cde07f558 100644 --- a/Tools/SystemDebug/system_debug_sample_build/License.txt +++ b/Tools/SystemDebug/system_debug_sample_build/License.txt @@ -1,4 +1,4 @@ -Copyright 2020 Intel Corporation +Copyright Intel Corporation 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: From 0032b0b04e82722e040a7cee8472a3ee524f8d49 Mon Sep 17 00:00:00 2001 From: JoeOster <52936608+JoeOster@users.noreply.github.com> Date: Wed, 19 Aug 2020 13:33:11 -0700 Subject: [PATCH 002/121] Update README.md --- README.md | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1fe987a98d..e5b25795c2 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,83 @@ -oneAPI-samples -This is the readme. +|Code sample name |Supported Intel(r) Architecture(s) |Description | +|-----------------------|-------------------------------------------|---------------| +|DirectPrograming/ | +|../DPC++/CombinationalLogic/Mandelbrot |GPU, CPU |Example of a fractal in mathematics | +|../DPC++/CombinationalLogic/Sepia-filter |GPU, CPU |Color image conversion using 1D range | +|../DPC++/DenseLinearAlgebra/Complex_mult |GPU, CPU |Complex number Multiplication | +|../DPC++/DenseLinearAlgebra/Matrix_mul |GPU, CPU |Simple program that multiplies two large matrices in parallel using DPC++, OpenMP and MKL | +|../DPC++/DenseLinearAlgebra/Simple-add |FPGA, GPU, CPU |Simple Add program | +|../DPC++/DenseLinearAlgebra/Vector-add |FPGA, GPU, CPU |Simple Vector add program | +|../DPC++/GraphTraversal/Bitonic-sort |GPU, CPU |Implementation of bitonic sort using DPC++. | +|../DPC++/ParallelPatterns/Dpc_reduce |GPU, CPU |A simple program that calculates pi, implemented using C++ and DPC++. | +|../DPC++/SpectralMethods/Discrete-cosine-transform |GPU, CPU |Image processing algorithm used in JPEG compression | +|../DPC++/StructuredGrids/1d_HeatTransfer |GPU, CPU |A simulation of one dimensional heat transfer process using DPC++. | +|../DPC++/StructuredGrids/ISO2DFD_DPCPP |GPU, CPU |A simple finite difference stencil kernel for solving 2D acoustic isotropic wave equation using DPC++ | +|../DPC++/StructuredGrids/ISO3DFD_DPCPP |GPU, CPU |A finite difference stencil kernel for solving 3D acoustic isotropic wave equation using DPC++ | +|../DPC++/StructuredGrids/Particle-diffusion |GPU, CPU |A simple implementation of a Monte Carlo simulation of the diffusion of water molecules in tissue | +|../C++/CombinationalLogic/Mandelbrot |CPU |Demonstrates how to accelerate Mandelbrot performance with SIMD and parallelization using OpenMP*. | +|../C++/CompilerInfrastructure/Intrinsics |CPU |Shows how to utilize the intrinsics supported by C++ compiler in a variety of applications. | +|../C++/GraphTraversal/Mergesort |CPU |Shows how to accelerate scalar merge sort program using OpenMP tasks | +|../FPGA/FPGATutorials/BestPractices/double_buffering |FPGA, CPU |See details under FPGATutorials | +|../FPGA/FPGATutorials/BestPractices/local_memory_cache |FPGA, CPU |See details under FPGATutorials | +|../FPGA/FPGATutorials/BestPractices/n_way_buffering |FPGA, CPU |See details under FPGATutorials | +|../FPGA/FPGATutorials/BestPractices/remove_loop_carried_dependency |FPGA, CPU |See details under FPGATutorials | +|../FPGA/FPGATutorials/BestPractices/triangular_loop |FPGA, CPU |See details under FPGATutorials | +|../FPGA/FPGATutorials/Compilation/compile_flow |FPGA, CPU |See details under FPGATutorials | +|../FPGA/FPGATutorials/Compilation/device_link |FPGA, CPU |See details under FPGATutorials | +|../FPGA/FPGATutorials/Compilation/use_library |FPGA, CPU |See details under FPGATutorials | +|../FPGA/FPGATutorials/FPGAExtensions/LoopAttributes/loop_ivdep |FPGA, CPU |See details under FPGATutorials | +|../FPGA/FPGATutorials/FPGAExtensions/LoopAttributes/loop_unroll |FPGA, CPU |See details under FPGATutorials | +|../FPGA/FPGATutorials/FPGAExtensions/LoopAttributes/max_concurrency |FPGA, CPU |See details under FPGATutorials | +|../FPGA/FPGATutorials/FPGAExtensions/Other/fpga_register |FPGA, CPU |See details under FPGATutorials | +|../FPGA/FPGATutorials/FPGAExtensions/Other/no_accessor_aliasing |FPGA, CPU |See details under FPGA Tutorials | +|../FPGA/FPGATutorials/FPGAExtensions/Other/system_profiling |FPGA, CPU |See details under FPGATutorials | +|../FPGA/FPGATutorials/FPGAExtensions/MemoryAttributes/memory_attributes_overview |FPGA, CPU |See details under FPGATutorials | +|../FPGA/FPGATutorials/FPGAExtensions/Pipes/pipe_array |FPGA |See details under FPGATutorials | +|../FPGA/FPGATutorials/FPGAExtensions/Pipes/pipes |FPGA |See details under FPGATutorials | +|../FPGA/FPGAExampleDesigns/crr |FPGA, CPU |See details under FPGAExampleDesigns | +|../FPGA/FPGAExampleDesigns/gzip |FPGA |See details under FPGAExampleDesigns | +|../FPGA/FPGAExampleDesigns/grd |FPGA, CPU |See details under FPGAExampleDesigns | +|Libraries | +|../oneDPL/Gamma-correction |GPU, CPU |gamma correction using Parallel STL | +|../oneDPL/Stable_sort_by_key |GPU, CPU |stable sort by key using counting_iterator and zip_iterator | +|../oneVPL/hello-decode |CPU |shows how to use oneVPL to perform a simple video decode | +|../oneVPL/hello-encode |CPU |shows how to use oneVPL to perform a simple video encode | +|Tools | +|../ApplicationDebugger/Debugger/array-transform |GPU, CPU |Array transform | +|../IoTConnectionTools/Analog-in |CPU |Analog pin input example using Eclipse* MRAA | +|../IoTConnectionTools/Digital In |CPU |GPIO pin input example using Eclipse* MRAA | +|../IoTConnectionTools/Digital Out |CPU |GPIO pin output example using Eclipse* MRAA | +|../IoTConnectionTools/Hello IoT World |CPU |Basic example that prints the compiler used during build | +|../IoTConnectionTools/Interrupt |CPU |Interrupt Service Routine example using Eclipse* MRAA | +|../IoTConnectionTools/Onboard Blink |CPU |Built-in LED blink for common IoT boards using Eclipse* MRAA | +|../IoTConnectionTools/PWM |CPU |Pulse Width Modulation pin output using Eclipse* MRAA | +|../IoTConnectionTools/Up2 LEDs |CPU |Built-in LED example for UP* Squared using Eclipse* MRAA | +|../SystemDebug/System Debug Sample Build |UEFI |Basic example that showcases the features of the Intel® System Debugger | + +#License + +The code samples are licensed under MIT license + +#Known issues or limitations + +##On Windows Platform +1. If you are using Visual Studio 2019, Visual Studio 2019 version 16.3.0 or newer is required. +2. To build samples on Windows, the required Windows SDK is ver. 10.0.17763.0. + + 1. If the SDK is not installed, use the following instructions below to avoid build failure: + + 1. Open the "code sample's" .sln from within Visual Studio 2017 or 2019, + 2. Right-click on the project name in "Solution Explorer" and select "Properties" + + 2. The project property dialog opens. + + 1. Select the "General" tab on the left, + 2. Select on the right side of the dialog box "Windows SDK Version"(2nd Item". + 3. Click on the drop-down icon to select a version that is installed on your system. + 4. click on [Ok] to save. + +3. Now you should be able to build the code sample. +4. For beta, FPGA samples support Windows through FPGA-emulator. +5. If you encounter a compilation error like below when building a sample program, one reason is that the directory path of the sample is too long; the work around is to move the sample to a directory like "c:\temp\sample_name". + * Error MSB6003 The specified task executable "dpcpp-cl.exe" could not be run ...... + From dadbdab1956969a3abd099a1e88f6ae7f5f62c46 Mon Sep 17 00:00:00 2001 From: akertesz <67655634+akertesz@users.noreply.github.com> Date: Wed, 19 Aug 2020 18:19:49 -0400 Subject: [PATCH 003/121] Fix FPGA entries --- README.md | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index e5b25795c2..9d1937f790 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -|Code sample name |Supported Intel(r) Architecture(s) |Description | +|Code Sample |Supported Intel(r) Architecture(s) |Description | |-----------------------|-------------------------------------------|---------------| |DirectPrograming/ | |../DPC++/CombinationalLogic/Mandelbrot |GPU, CPU |Example of a fractal in mathematics | @@ -14,29 +14,31 @@ |../DPC++/StructuredGrids/ISO2DFD_DPCPP |GPU, CPU |A simple finite difference stencil kernel for solving 2D acoustic isotropic wave equation using DPC++ | |../DPC++/StructuredGrids/ISO3DFD_DPCPP |GPU, CPU |A finite difference stencil kernel for solving 3D acoustic isotropic wave equation using DPC++ | |../DPC++/StructuredGrids/Particle-diffusion |GPU, CPU |A simple implementation of a Monte Carlo simulation of the diffusion of water molecules in tissue | +|../DPC++FPGA/ReferenceDesigns/crr |FPGA |High-performance CRR binomial tree option pricing model using DPC++ on FPGA| +|../DPC++FPGA/ReferenceDesigns/gzip |FPGA |High-performance GZIP compression using DPC++ on FPGA| +|../DPC++FPGA/ReferenceDesigns/qrd |FPGA |High-performance QR decomposition of matrices using DPC++ on FPGA| +|../DPC++FPGA/Tutorials/GettingStarted/fpga_compile |FPGA |Tutorial introducing how to compile DPC++ for FPGA | +|../DPC++FPGA/Tutorials/GettingStarted/fast_recompile |FPGA |Tutorial introducing host-only recompile to save DPC++ development time on FPGA | +|../DPC++FPGA/Tutorials/Tools/use_library |FPGA |Tutorial showing how to use cross-language libraries in DPC++ on FPGA | +|../DPC++FPGA/Tutorials/Tools/system_profiling |FPGA |Tutorial showing how to use the OpenCL Intercept Layer to profile DPC++ designs running on FPGA | +|../DPC++FPGA/Tutorials/DesignPatterns/double_buffering |FPGA |Tutorial demonstrating how to overlap kernel execution with buffer transfers and host processing | +|../DPC++FPGA/Tutorials/DesignPatterns/n_way_buffering |FPGA |Tutorial demonstrating an extension of double buffering to n-way buffering | +|../DPC++FPGA/Tutorials/DesignPatterns/onchip_memory_cache |FPGA |Tutorial demonstrating the caching of on-chip memory to reduce loop initiation interval on FPGA | +|../DPC++FPGA/Tutorials/DesignPatterns/pipe_array |FPGA |Tutorial demonstrating how to create an array of pipes | +|../DPC++FPGA/Tutorials/DesignPatterns/remove_loop_carried_dependency |FPGA |Tutorial demonstrating a technique to optimize performance by removing loop carried dependencies | +|../DPC++FPGA/Tutorials/DesignPatterns/triangular_loop |FPGA |Tutorial demonstrating an advanced FPGA optimization technique for triangular loops | +|../DPC++FPGA/Tutorials/Features/fpga_reg |FPGA |Tutorial demonstrating the use of the DPC++ FPGA power user extension intel::fpga_reg | +|../DPC++FPGA/Tutorials/Features/kernel_args_restrict |FPGA |Tutorial demonstrating how to avoid performance penalties due to kernel argument aliasing | +|../DPC++FPGA/Tutorials/Features/loop_coalesce |FPGA |Tutorial demonstrating the DPC++ FPGA loop_coalesce attribute | +|../DPC++FPGA/Tutorials/Features/loop_ivdep |FPGA |Tutorial demonstrating the use of the loop ivdep attribute | +|../DPC++FPGA/Tutorials/Features/loop_unroll |FPGA |Tutorial demonstrating the DPC++ unroll pragma and its performance trade-offs on FPGA | +|../DPC++FPGA/Tutorials/Features/max_concurrency |FPGA |Tutorial demonstrating the DPC++ FPGA max_concurrency attribute | +|../DPC++FPGA/Tutorials/Features/memory_attributes |FPGA |Tutorial demonstrating how to use DPC++ FPGA memory attributes | +|../DPC++FPGA/Tutorials/Features/pipes |FPGA |Tutorial demonstrating the DPC++ FPGA pipes extension to transfer data between kernels | +|../DPC++FPGA/Tutorials/Features/speculated_iterations |FPGA |Tutorial demonstrating the DPC++ FPGA speculated_iterations attribute | |../C++/CombinationalLogic/Mandelbrot |CPU |Demonstrates how to accelerate Mandelbrot performance with SIMD and parallelization using OpenMP*. | |../C++/CompilerInfrastructure/Intrinsics |CPU |Shows how to utilize the intrinsics supported by C++ compiler in a variety of applications. | |../C++/GraphTraversal/Mergesort |CPU |Shows how to accelerate scalar merge sort program using OpenMP tasks | -|../FPGA/FPGATutorials/BestPractices/double_buffering |FPGA, CPU |See details under FPGATutorials | -|../FPGA/FPGATutorials/BestPractices/local_memory_cache |FPGA, CPU |See details under FPGATutorials | -|../FPGA/FPGATutorials/BestPractices/n_way_buffering |FPGA, CPU |See details under FPGATutorials | -|../FPGA/FPGATutorials/BestPractices/remove_loop_carried_dependency |FPGA, CPU |See details under FPGATutorials | -|../FPGA/FPGATutorials/BestPractices/triangular_loop |FPGA, CPU |See details under FPGATutorials | -|../FPGA/FPGATutorials/Compilation/compile_flow |FPGA, CPU |See details under FPGATutorials | -|../FPGA/FPGATutorials/Compilation/device_link |FPGA, CPU |See details under FPGATutorials | -|../FPGA/FPGATutorials/Compilation/use_library |FPGA, CPU |See details under FPGATutorials | -|../FPGA/FPGATutorials/FPGAExtensions/LoopAttributes/loop_ivdep |FPGA, CPU |See details under FPGATutorials | -|../FPGA/FPGATutorials/FPGAExtensions/LoopAttributes/loop_unroll |FPGA, CPU |See details under FPGATutorials | -|../FPGA/FPGATutorials/FPGAExtensions/LoopAttributes/max_concurrency |FPGA, CPU |See details under FPGATutorials | -|../FPGA/FPGATutorials/FPGAExtensions/Other/fpga_register |FPGA, CPU |See details under FPGATutorials | -|../FPGA/FPGATutorials/FPGAExtensions/Other/no_accessor_aliasing |FPGA, CPU |See details under FPGA Tutorials | -|../FPGA/FPGATutorials/FPGAExtensions/Other/system_profiling |FPGA, CPU |See details under FPGATutorials | -|../FPGA/FPGATutorials/FPGAExtensions/MemoryAttributes/memory_attributes_overview |FPGA, CPU |See details under FPGATutorials | -|../FPGA/FPGATutorials/FPGAExtensions/Pipes/pipe_array |FPGA |See details under FPGATutorials | -|../FPGA/FPGATutorials/FPGAExtensions/Pipes/pipes |FPGA |See details under FPGATutorials | -|../FPGA/FPGAExampleDesigns/crr |FPGA, CPU |See details under FPGAExampleDesigns | -|../FPGA/FPGAExampleDesigns/gzip |FPGA |See details under FPGAExampleDesigns | -|../FPGA/FPGAExampleDesigns/grd |FPGA, CPU |See details under FPGAExampleDesigns | |Libraries | |../oneDPL/Gamma-correction |GPU, CPU |gamma correction using Parallel STL | |../oneDPL/Stable_sort_by_key |GPU, CPU |stable sort by key using counting_iterator and zip_iterator | From 11fdd3b55d3fa56278ea65ab79997fcfd97f5edb Mon Sep 17 00:00:00 2001 From: JoeOster <52936608+JoeOster@users.noreply.github.com> Date: Thu, 20 Aug 2020 12:57:12 -0700 Subject: [PATCH 004/121] Update README.md Updates per request of sranikonda --- README.md | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 9d1937f790..8af0181245 100644 --- a/README.md +++ b/README.md @@ -63,23 +63,10 @@ The code samples are licensed under MIT license #Known issues or limitations ##On Windows Platform -1. If you are using Visual Studio 2019, Visual Studio 2019 version 16.3.0 or newer is required. +1. If you are using Visual Studio 2019, Visual Studio 2019 version 16.4.0 or newer is required. 2. To build samples on Windows, the required Windows SDK is ver. 10.0.17763.0. - - 1. If the SDK is not installed, use the following instructions below to avoid build failure: - - 1. Open the "code sample's" .sln from within Visual Studio 2017 or 2019, - 2. Right-click on the project name in "Solution Explorer" and select "Properties" - - 2. The project property dialog opens. - - 1. Select the "General" tab on the left, - 2. Select on the right side of the dialog box "Windows SDK Version"(2nd Item". - 3. Click on the drop-down icon to select a version that is installed on your system. - 4. click on [Ok] to save. - 3. Now you should be able to build the code sample. 4. For beta, FPGA samples support Windows through FPGA-emulator. 5. If you encounter a compilation error like below when building a sample program, one reason is that the directory path of the sample is too long; the work around is to move the sample to a directory like "c:\temp\sample_name". - * Error MSB6003 The specified task executable "dpcpp-cl.exe" could not be run ...... + * Error MSB6003 The specified task executable "dpcpp.exe" could not be run ...... From c9f8629a26fb2562927fd4c27a75eea09a2a5b10 Mon Sep 17 00:00:00 2001 From: JoeOster <52936608+JoeOster@users.noreply.github.com> Date: Sun, 23 Aug 2020 07:52:06 -0700 Subject: [PATCH 005/121] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8af0181245..ee7e072fe3 100644 --- a/README.md +++ b/README.md @@ -56,13 +56,13 @@ |../IoTConnectionTools/Up2 LEDs |CPU |Built-in LED example for UP* Squared using Eclipse* MRAA | |../SystemDebug/System Debug Sample Build |UEFI |Basic example that showcases the features of the Intel® System Debugger | -#License +# License The code samples are licensed under MIT license -#Known issues or limitations +# Known issues or limitations -##On Windows Platform +## On Windows Platform 1. If you are using Visual Studio 2019, Visual Studio 2019 version 16.4.0 or newer is required. 2. To build samples on Windows, the required Windows SDK is ver. 10.0.17763.0. 3. Now you should be able to build the code sample. From 84ce0f1bd5c638512873435ba1e1c1455b58081b Mon Sep 17 00:00:00 2001 From: Joseph Oster Date: Wed, 26 Aug 2020 09:37:45 -0700 Subject: [PATCH 006/121] removing duplicate samples after transfering to dwarves folders --- .../Fortran/openmp_samples/License.txt | 7 - .../Fortran/openmp_samples/Makefile | 37 --- .../Fortran/openmp_samples/README.md | 98 -------- .../Fortran/openmp_samples/sample.json | 30 --- .../openmp_samples/src/openmp_sample.f90 | 117 --------- .../Fortran/optimize_samples/License.txt | 7 - .../Fortran/optimize_samples/Makefile | 38 --- .../Fortran/optimize_samples/README.md | 194 --------------- .../Fortran/optimize_samples/sample.json | 22 -- .../Fortran/optimize_samples/src/int_sin.f90 | 96 -------- .../Fortran/vec_samples/License.txt | 7 - .../Fortran/vec_samples/Makefile | 30 --- .../Fortran/vec_samples/README.md | 224 ------------------ .../Fortran/vec_samples/sample.json | 22 -- .../Fortran/vec_samples/src/driver.f90 | 69 ------ .../Fortran/vec_samples/src/matvec.f90 | 30 --- 16 files changed, 1028 deletions(-) delete mode 100644 DirectProgramming/Fortran/openmp_samples/License.txt delete mode 100644 DirectProgramming/Fortran/openmp_samples/Makefile delete mode 100644 DirectProgramming/Fortran/openmp_samples/README.md delete mode 100644 DirectProgramming/Fortran/openmp_samples/sample.json delete mode 100644 DirectProgramming/Fortran/openmp_samples/src/openmp_sample.f90 delete mode 100644 DirectProgramming/Fortran/optimize_samples/License.txt delete mode 100644 DirectProgramming/Fortran/optimize_samples/Makefile delete mode 100644 DirectProgramming/Fortran/optimize_samples/README.md delete mode 100644 DirectProgramming/Fortran/optimize_samples/sample.json delete mode 100644 DirectProgramming/Fortran/optimize_samples/src/int_sin.f90 delete mode 100644 DirectProgramming/Fortran/vec_samples/License.txt delete mode 100644 DirectProgramming/Fortran/vec_samples/Makefile delete mode 100644 DirectProgramming/Fortran/vec_samples/README.md delete mode 100644 DirectProgramming/Fortran/vec_samples/sample.json delete mode 100644 DirectProgramming/Fortran/vec_samples/src/driver.f90 delete mode 100644 DirectProgramming/Fortran/vec_samples/src/matvec.f90 diff --git a/DirectProgramming/Fortran/openmp_samples/License.txt b/DirectProgramming/Fortran/openmp_samples/License.txt deleted file mode 100644 index 415025cf03..0000000000 --- a/DirectProgramming/Fortran/openmp_samples/License.txt +++ /dev/null @@ -1,7 +0,0 @@ -Copyright Intel Corporation - -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. diff --git a/DirectProgramming/Fortran/openmp_samples/Makefile b/DirectProgramming/Fortran/openmp_samples/Makefile deleted file mode 100644 index baefe44f8c..0000000000 --- a/DirectProgramming/Fortran/openmp_samples/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -## ============================================================= -## Copyright © 2020 Intel Corporation -## -## SPDX-License-Identifier: MIT -## ============================================================= -## -## -##****************************************************************************** -## Content: -## -## Build for openmp_sample -##****************************************************************************** - -FC = ifort - -release: openmp_sample.exe - -debug: openmp_sample_dbg.exe - -run: release ; @export DYLD_LIBRARY_PATH="$(LIBRARY_PATH)" ; ./openmp_sample.exe - -debug_run: debug ; @export DYLD_LIBRARY_PATH="$(LIBRARY_PATH)" ; ./openmp_sample_dbg.exe - -openmp_sample.exe: openmp_sample.o - $(FC) -O2 -fpp -qopenmp $^ -o $@ - -openmp_sample_dbg.exe: openmp_sample_dbg.o - $(FC) -O0 -g -fpp -qopenmp $^ -o $@ - -%.o: src/%.f90 - $(FC) -O2 -c -fpp -qopenmp -o $@ $< - -%_dbg.o: src/%.f90 - $(FC) -O0 -g -c -fpp -qopenmp -o $@ $< - -clean: - /bin/rm -f core.* *.o *.exe diff --git a/DirectProgramming/Fortran/openmp_samples/README.md b/DirectProgramming/Fortran/openmp_samples/README.md deleted file mode 100644 index a9610afc6b..0000000000 --- a/DirectProgramming/Fortran/openmp_samples/README.md +++ /dev/null @@ -1,98 +0,0 @@ -# `Fortran OpenMP*` sample -This sample is designed to illustrate how to use -the OpenMP* API with the Intel® Fortran Compiler. - -This program finds all primes in the first 40,000,000 integers, -the number of 4n+1 primes, and the number of 4n-1 primes in the same range. -It illustrates two OpenMP* directives to help speed up the code. - - -| Optimized for | Description -|:--- |:--- -| OS | macOS* with Xcode* installed -| Software | Intel® oneAPI Intel Fortran Compiler (Beta) -| What you will learn | How to build and run a Fortran OpenMP application using Intel Fortran compiler -| Time to complete | 10 minutes - -## Purpose - -This program finds all primes in the first 40,000,000 integers, the number of 4n+1 primes, -and the number of 4n-1 primes in the same range. It illustrates two OpenMP* directives -to help speed up the code. - -First, a dynamic schedule clause is used with the OpenMP* for directive. -Because the for loop's workload increases as its index gets bigger, -the default static scheduling does not work well. Instead, dynamic scheduling -is used to account for the increasing workload. -But dynamic scheduling itself has more overhead than static scheduling, -so a chunk size of 10 is used to reduce the overhead for dynamic scheduling. - -Second, a reduction clause is used instead of an OpenMP* critical directive -to eliminate lock overhead. A critical directive would cause excessive lock overhead -due to the one-thread-at-time update of the shared variables each time through the for loop. -Instead the reduction clause causes only one update of the shared variables once at the end of the loop. - -The sample can be compiled unoptimized (-O0 ), or at any level of -optimization (-O1 through -O3 ). In addition, the following compiler options are needed. - -The option -qopenmp enables compiler recognition of OpenMP* directives. -This option can also be omitted, in which case the generated executable will be a serial program. - -The option -fpp enables the Fortran preprocessor. -Read the Intel® Fortran Compiler Documentation for more information about these options. - -## Key Implementation Details -The Intel® oneAPI Intel Fortran Compiler (Beta) includes all libraries and headers necessary to compile and run OpenMP* enabled Fortran applications. Users simply use the -qopenmp compiler option to compile and link their OpenMP enabled applications. - -## License -This code sample is licensed under MIT license - -## Building the `Fortran OpenMP*` sample - -### Experiment 1: Unoptimized build and run -* Build openmp_samples - - cd openmp_samples - make clean - make debug - - * Run the program - - make debug_run - - * What did you see? - - Did the debug, unoptimized code run slower? - -### Experiment 2: Default Optimized build and run - - * Build openmp_samples - - make - * Run the program - - make run - -### Experiment 3: Controlling number of threads -By default an OpenMP application creates and uses as many threads as there are "processors" in a system. A "processor" is the number of logical processors which on hyperthreaded cores is twice the number of physical cores. - -OpenMP uses environment variable 'OMP_NUM_THREADS' to set number of threads to use. Try this! - - export OMP_NUM_THREADS=1 - make run -note the number of threads reported by the application. Now try 2 threads: - - export OMP_NUM_THREADS=2 - make run -Did the make the application run faster? Experiment with the number of threads and see how it affects performance. - -### Clean up - * Clean the program - make clean - -## Further Reading -Interested in learning more? We have a wealth of information -on using OpenMP with the Intel Fortran Compiler in our -[OpenMP section of Developer Guide and Reference][1] - -[1]: https://software.intel.com/content/www/us/en/develop/documentation/fortran-compiler-developer-guide-and-reference/top/optimization-and-programming-guide/openmp-support.html "Developer Guide and Reference" diff --git a/DirectProgramming/Fortran/openmp_samples/sample.json b/DirectProgramming/Fortran/openmp_samples/sample.json deleted file mode 100644 index c7a512744c..0000000000 --- a/DirectProgramming/Fortran/openmp_samples/sample.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "openmp_samples", - "categories": [ "Toolkit/Intel® oneAPI HPC Toolkit" ], - "description": "Fortran Tutorial - Using OpenMP", - "toolchain": [ "ifort" ], - "languages": [ { "fortran": {} } ], - "targetDevice": [ "CPU" ], - "os": [ "darwin" ], - "builder": [ "make" ], - "ciTests":{ - "darwin": [ - { - "id": "fort_release_cpu", - "steps": [ - "make release", - "make run", - "make clean" - ] - }, - { - "id": "fort_debug_cpu", - "steps": [ - "make debug", - "make debug_run", - "make clean" - ] - } - ] - } -} diff --git a/DirectProgramming/Fortran/openmp_samples/src/openmp_sample.f90 b/DirectProgramming/Fortran/openmp_samples/src/openmp_sample.f90 deleted file mode 100644 index fb0a9ebacf..0000000000 --- a/DirectProgramming/Fortran/openmp_samples/src/openmp_sample.f90 +++ /dev/null @@ -1,117 +0,0 @@ -! ============================================================== -! Copyright © 2020 Intel Corporation -! -! SPDX-License-Identifier: MIT -! ============================================================= -! -! [DESCRIPTION] -! This code finds all primes in the first 40,000,000 integers, the number of -! 4n+1 primes, and the number of 4n-1 primes in the same range. -! -! This source illustrates two OpenMP directives to help speed up -! the code. First, a dynamic "schedule" clause is used with the OpenMP "for" -! directive. Because the "for" loop's workload increases as its index -! gets bigger, the default "static" scheduling does not work well. -! Instead dynamic scheduling is used to account for the increasing -! workload. But dynamic scheduling itself has more overhead than -! static scheduling, so a "chunk size" of 10 is used to reduce the -! overhead for dynamic scheduling. Second, a "reduction" clause is -! used instead of an OpenMP "critical" directive to eliminate lock overhead. -! A "critical" directive would cause excessive lock overhead due to -! the one-thread-at-time update of the shared variables each -! time through the "for" loop. Instead the reduction clause causes only -! one update of the shared variables once at the end of the loop. -! -! [COMPILE] -! Use the following compiler options to compile both multi- and -! single-threaded versions. -! -! Parallel compilation: -! -! Windows*: /Qopenmp /fpp -! -! Linux* and macOS*: -qopenmp -fpp -! -! Serial compilation: -! -! Use the same command, but omit the -fopenmp (Linux* and macOS*) -! or /Qopenmp (Windows) option. -! - -program ompPrime - -#ifdef _OPENMP - include 'omp_lib.h' !needed for OMP_GET_NUM_THREADS() -#endif - -integer :: start = 1 -integer :: end = 40000000 -integer :: number_of_primes = 0 -integer :: number_of_41primes = 0 -integer :: number_of_43primes = 0 -integer index, factor, limit, nthr -real rindex, rlimit -logical prime, print_primes - -print_primes = .false. -nthr = 1 ! assume just one thread -print *, ' Range to check for Primes:',start,end - -#ifdef _OPENMP -!$omp parallel - -!$omp single - nthr = OMP_GET_NUM_THREADS() - print *, ' We are using',nthr,' thread(s)' -!$omp end single -! - -! -!$omp do private(factor, limit, prime) & - schedule(dynamic,10) & - reduction(+:number_of_primes,number_of_41primes,number_of_43primes) -#else - print *, ' We are using',nthr,' thread(s)' -#endif - -do index = start, end, 2 !workshared loop - - limit = int(sqrt(real(index))) - prime = .true. ! assume number is prime - factor = 3 - - do - if(prime .and. factor .le. limit) then - if(mod(index,factor) .eq. 0) then - prime = .false. - endif - factor = factor + 2 - else - exit ! we can jump out of non-workshared loop - endif - enddo - - if(prime) then - if(print_primes) then - print *, index, ' is prime' - endif - - number_of_primes = number_of_primes + 1 - - if(mod(index,4) .eq. 1) then - number_of_41primes = number_of_41primes + 1 - endif - - if(mod(index,4) .eq. 3) then - number_of_43primes = number_of_43primes + 1 - endif - - endif ! if(prime) -enddo -!$omp end do -!$omp end parallel - -print *, ' Number of primes found:',number_of_primes -print *, ' Number of 4n+1 primes found:',number_of_41primes -print *, ' Number of 4n-1 primes found:',number_of_43primes -end program ompPrime diff --git a/DirectProgramming/Fortran/optimize_samples/License.txt b/DirectProgramming/Fortran/optimize_samples/License.txt deleted file mode 100644 index 415025cf03..0000000000 --- a/DirectProgramming/Fortran/optimize_samples/License.txt +++ /dev/null @@ -1,7 +0,0 @@ -Copyright Intel Corporation - -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. diff --git a/DirectProgramming/Fortran/optimize_samples/Makefile b/DirectProgramming/Fortran/optimize_samples/Makefile deleted file mode 100644 index 2960bf3f8f..0000000000 --- a/DirectProgramming/Fortran/optimize_samples/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -## ============================================================= -## Copyright © 2020 Intel Corporation -## -## SPDX-License-Identifier: MIT -## ============================================================= -## -## -##****************************************************************************** -## Content: -## -## Build for optimize_sample -##****************************************************************************** -# -# >>>>> SET OPTIMIZATION LEVEL BELOW <<<<< -# -#Uncomment one of the following with which you wish to compile - -FC = ifort -O0 -#FC = ifort -O1 -#FC = ifort -O2 -#FC = ifort -O3 - -OBJS = int_sin.o - -all: int_sin - -run: int_sin - ./int_sin - -int_sin: $(OBJS) - ifort $^ -o $@ - -%.o: src/%.f90 - $(FC) $^ -c - -clean: - /bin/rm -f core.* $(OBJS) int_sin - diff --git a/DirectProgramming/Fortran/optimize_samples/README.md b/DirectProgramming/Fortran/optimize_samples/README.md deleted file mode 100644 index 8681e3a9ac..0000000000 --- a/DirectProgramming/Fortran/optimize_samples/README.md +++ /dev/null @@ -1,194 +0,0 @@ -# `Fortran Optimization` sample - -This sample is designed to illustrate compiler optimization features and programming concepts. - -This program computes the integral (area under the curve) of a user-supplied function -over an interval in a stepwise fashion. -The interval is split into segments, and at each segment position the area of a rectangle -is computed whose height is the value of sine at that point and the width is the segment width. -The areas of the rectangles are then summed. - -The process is repeated with smaller and smaller width rectangles, -more closely approximating the true value. - -The source for this program also demonstrates recommended Fortran coding practices. - -| Optimized for | Description -|:--- |:--- -| OS | macOS* with Xcode* installed -| Software | Intel® oneAPI Intel® Fortran Compiler (Beta) -| What you will learn | Optimization using the Intel® Fortran compiler -| Time to complete | 15 minutes - -## Purpose - -The Intel® Fortran Compiler can optimize applications for performance. The primary compiler option is -O followed by a numeric optimizaiton "level" from 0 requesting no optimization to 3, which requests all compiler optimizations for the application. The -O optimizaition levels are: - - * O0 - No optimizations - * O1 - Enables optimizations for speed and disables some optimizations that increase code size and affect speed. - * O2 - Enables optimizations for speed. This is the generally recommended optimization level. Vectorization is enabled at O2 and higher levels. - * O3 - Performs O2 optimizations and enables more aggressive loop transformations such as Fusion, Block-Unroll-and-Jam, and collapsing IF statements. - -Read the [Intel® Fortran Compiler Developer Guide and Reference][1] -[1]: https://software.intel.com/content/www/us/en/develop/documentation/fortran-compiler-developer-guide-and-reference/top.html "Intel® Fortran Compiler Developer Guide and Reference" -for more information about these options. - -Some of these compiler optimizations use features and options that can -restrict program execution to specific architectures. - - -## License -This code sample is licensed under MIT license - -## Building the `Fortran Optimization` sample - -Use the one of the following compiler options: - - -### macOS* : -O0 -O1, -O2, -O3 - -### STEP 1: Build and run with -O0 -cd optimize_samples - -Edit 'Makefile' using your favorite editor - -To set optimization level uncomment FC = ifort -O0 like this - - FC = ifort -O0 - #FC = ifort -O1 - #FC = ifort -O2 - #FC = ifort -O3 - * Build the executable with 'make' - - make - - * Run the program - - make run - - * Note the final run time (example) - CPU Time = 3.776983 seconds - - * Clean the files we built - - make clean - - -### STEP 2: Build and run with -O1 -Edit 'Makefile' using your favorite editor - -To set optimization level uncomment FC = ifort -O1 like this - - #FC = ifort -O0 - FC = ifort -O1 - #FC = ifort -O2 - #FC = ifort -O3 - * Build the executable with 'make' - - make - - * Run the program - - make run - - * Note the final run time (example) - CPU Time = 1.444569 seconds - - * Clean the files we built - - make clean - - -### STEP 3: Build and run with -O2 -Edit 'Makefile' using your favorite editor - -To set optimization level uncomment FC = ifort -O2 like this - - #FC = ifort -O0 - #FC = ifort -O1 - FC = ifort -O2 - #FC = ifort -O3 - * Build the executable with 'make' - - make - - * Run the program - - make run - - * Note the final run time (example) - CPU Time = 0.5143980 seconds - - * Clean the files we built - - make clean - -### STEP 4: Build and run with -O3 -Edit 'Makefile' using your favorite editor - -To set optimization level uncomment FC = ifort -O3 like this - - #FC = ifort -O0 - #FC = ifort -O1 - #FC = ifort -O2 - FC = ifort -O3 - * Build the executable with 'make' - - make - - * Run the program - - make run - - * Note the final run time (example) - CPU Time = 0.5133380 seconds - - * Clean the files we built - - make clean - -## What did we learn? -There are big jumps going from O0 to O1, and from O1 to O2. -But we see very little performance gain going from O2 to O3. -This does vary by application but generally with Intel® Compilers -O2 is has most optimizations. Sometimes O3 can help, of course, -but generally O2 is sufficient for most applications. - -### Further Exploration -The Intel® Fortran Compiler has many options for optimization. -If you have a genuine Intel® Architecture processor, try these additional options - - edit 'Makefile' using your favorite editor. To set additional optimizations uncomment FC = ifort -O3 and add additional options shown: - - #FC = ifort -O0 - #FC = ifort -O1 - #FC = ifort -O2 - FC = ifort -O3 -xhost -align array64byte - * Build the executable with the new options -xhost -align array64byte - - make - - * Run the program - - make run - - * Note the final run time (example) - CPU Time = 0.2578490 seconds - - * Clean the program - - make clean - -There are 2 additional compiler options here that are worth mentioning: Read the online -[Developer Guide and Reference][3] for more information about -these options -[3]: https://software.intel.com/content/www/us/en/develop/documentation/fortran-compiler-developer-guide-and-reference/top.html "Developer Guide and Reference" - 1. -xhost (sub option of -x option): [-x][4] - [4]: https://software.intel.com/content/www/us/en/develop/documentation/fortran-compiler-developer-guide-and-reference/top/compiler-reference/compiler-options/compiler-option-details/code-generation-options/x-qx.html "-x option" - 2. -align array64byte: [-align][5] - [5]: https://software.intel.com/content/www/us/en/develop/documentation/fortran-compiler-developer-guide-and-reference/top/compiler-reference/compiler-options/compiler-option-details/data-options/align.html "-align option" - -### Clean up - * Clean the program - make clean - diff --git a/DirectProgramming/Fortran/optimize_samples/sample.json b/DirectProgramming/Fortran/optimize_samples/sample.json deleted file mode 100644 index 0cd201d97e..0000000000 --- a/DirectProgramming/Fortran/optimize_samples/sample.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "optimization_samples", - "categories": [ "Toolkit/Intel® oneAPI HPC Toolkit" ], - "description": "Fortran Sample - Simple Compiler Optimizations", - "toolchain": [ "ifort" ], - "languages": [ { "fortran": {} } ], - "targetDevice": [ "CPU" ], - "os": [ "darwin" ], - "builder": [ "make" ], - "ciTests":{ - "darwin": [ - { - "id": "fort_optsample_cpu", - "steps": [ - "make", - "make run", - "make clean" - ] - } - ] - } -} diff --git a/DirectProgramming/Fortran/optimize_samples/src/int_sin.f90 b/DirectProgramming/Fortran/optimize_samples/src/int_sin.f90 deleted file mode 100644 index d1519820f3..0000000000 --- a/DirectProgramming/Fortran/optimize_samples/src/int_sin.f90 +++ /dev/null @@ -1,96 +0,0 @@ - ! ============================================================== - ! Copyright © 2020 Intel Corporation - ! - ! SPDX-License-Identifier: MIT - ! ============================================================= - ! - ! [DESCRIPTION] - ! This program computes the integral (area under the curve) of a user-supplied - ! function over an interval in a stepwise fashion. The interval is split into - ! segments, and at each segment position the area of a rectangle is computed - ! whose height is the value of sine at that point and the width is the segment - ! width. The areas of the rectangles are then summed. - ! - ! The process is repeated with smaller and smaller width rectangles, more - ! closely approximating the true value. - ! - ! The source for this program also demonstrates recommended Fortran - ! coding practices. - ! - ! Compile the sample several times using different optimization options. - ! - ! Read the Intel(R) Fortran Compiler Documentation for more information about these options. - ! - ! Some of these automatic optimizations use features and options - ! that can restrict program execution to specific architectures. - ! - ! [COMPILE] - ! Use the one of the following compiler options: - ! - ! Windows*: /O1, /O2, /O3 - ! - ! Linux* and macOS*: -O1, -O2, -O3 - ! - -program int_sin -implicit none - -! Create a value DP that is the "kind" number of a double precision value -! We will use this value in our declarations and constants. -integer, parameter :: DP = kind(0.0D0) - -! Declare a named constant for pi, specifying the kind type -real(DP), parameter :: pi = 3.141592653589793238_DP - -! Declare interval begin and end -real(DP), parameter :: interval_begin = 0.0_DP -real(DP), parameter :: interval_end = 2.0_DP * pi - -real(DP) :: step, sum, x_i -integer :: N, i, j -real clock_start, clock_finish - -write (*,'(A)') " " -write (*,'(A)') " Number of | Computed Integral |" -write (*,'(A)') " Interior Points | |" -call cpu_time (clock_start) - -do j=2,26 - write (*,'(A)') "--------------------------------------" - N = 2**j - ! Compute stepsize for N-1 internal rectangles - step = (interval_end - interval_begin) / real(N,DP); - - ! Approximate 1/2 area in first rectangle: f(x0) * (step/2) - sum = INTEG_FUNC(interval_begin) * (step / 2.0_DP) - - do i=1,N-1 - x_i = real(i,DP) * step - ! Apply midpoint rule: - ! Given length = f(x), compute the area of the - ! rectangle of width step - sum = sum + (INTEG_FUNC(x_i) * step) - end do - - ! Add approximate area in last rectangle for f(xN) * (step/2) - sum = sum + (INTEG_FUNC(interval_end) * (step / 2.0_DP)) - - write (*,'(T5,I10,T18,"|",2X,1P,E14.7,T38,"|")') N, sum - end do - -call cpu_time(clock_finish) -write (*,'(A)') "--------------------------------------" -write (*,'(A)') " " -write (*,*) "CPU Time = ",(clock_finish - clock_start), " seconds" - -contains - -! Function to integrate -real(DP) function INTEG_FUNC (x) - real(DP), intent(IN) :: x - - INTEG_FUNC = abs(sin(x)) - return -end function INTEG_FUNC - -end program int_sin diff --git a/DirectProgramming/Fortran/vec_samples/License.txt b/DirectProgramming/Fortran/vec_samples/License.txt deleted file mode 100644 index 415025cf03..0000000000 --- a/DirectProgramming/Fortran/vec_samples/License.txt +++ /dev/null @@ -1,7 +0,0 @@ -Copyright Intel Corporation - -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. diff --git a/DirectProgramming/Fortran/vec_samples/Makefile b/DirectProgramming/Fortran/vec_samples/Makefile deleted file mode 100644 index 3641610d5f..0000000000 --- a/DirectProgramming/Fortran/vec_samples/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -## ============================================================= -## Copyright © 2020 Intel Corporation -## -## SPDX-License-Identifier: MIT -## ============================================================= -## -## -##****************************************************************************** -## Content: -## -## Build for vec_sample -##****************************************************************************** -# -FC=ifort -FFLAGS=-O2 -qopt-report-phase=vec -qopt-report=2 -OBJ=src/driver.o src/matvec.o - -all : matvec - -run : matvec - ./matvec - -src/%.o: src/%.f90 - $(FC) $(FFLAGS) -c $< -o $@ - -matvec: $(OBJ) - $(FC) -V $^ -o matvec - -clean: - -rm -f matvec $(OBJ) src/*.optrpt diff --git a/DirectProgramming/Fortran/vec_samples/README.md b/DirectProgramming/Fortran/vec_samples/README.md deleted file mode 100644 index 32cb08e5c6..0000000000 --- a/DirectProgramming/Fortran/vec_samples/README.md +++ /dev/null @@ -1,224 +0,0 @@ -# `Fortran Vectorization` sample - -In this sample, you will use the auto-vectorizer to improve the performance -of the sample application. You will compare the performance of the -serial version and the version that was compiled with the auto-vectorizer. - -| Optimized for | Description -|:--- |:--- -| OS | macOS* with Xcode* installed -| Hardware | Intel-based Mac* -| Software | Intel® oneAPI Intel Fortran Compiler (beta) -| What you will learn | Vectorization using Intel Fortran compiler -| Time to complete | 15 minutes - - -## Purpose -The Intel® Compiler has an auto-vectorizer that detects operations in the application -that can be done in parallel and converts sequential operations -to parallel operations by using the -Single Instruction Multiple Data (SIMD) instruction set. - -For the Intel® compiler, vectorization is the unrolling of a loop combined with the generation of packed SIMD instructions. Because the packed instructions operate on more than one data element at a time, the loop can execute more efficiently. It is sometimes referred to as auto-vectorization to emphasize that the compiler automatically identifies and optimizes suitable loops on its own. - -Intel® Advisor can assist with vectorization and show optimization report messages with your source code. See [Intel Advisor][1] for details. -[1]: https://software.intel.com/en-us/intel-advisor-xe "Intel Avisor" - -Vectorization may call library routines that can result in additional performance gain on Intel microprocessors than on non-Intel microprocessors. The vectorization can also be affected by certain options, such as m or x. - -Vectorization is enabled with the compiler at optimization levels of O2 (default level) and higher for both Intel® microprocessors and non-Intel® microprocessors. Many loops are vectorized automatically, but in cases where this doesn't happen, you may be able to vectorize loops by making simple code modifications. In this sample, you will: - -1. establish a performance baseline - -2. generate a vectorization report - -3. improve performance by aligning data - -4. improve performance using Interprocedural Optimization - -## Key Implementation Details - -In this sample, you will use the following files: - - driver.f90 - - matvec.f90 - - -## License -This code sample is licensed under MIT license - - -## Building the `Fortran Vectorization` sample - -This sample contains 2 Fortran source files, in subdirectory 'src/' under the main sample root directory oneAPI-samples/DirectProgramming/Fortran/vec_samples - -1. matvec.f90 is a Fortran source file with a matrix-times-vector algorithm -2. driver.f90 is a Fortran source file with the main program calling matvec - -## Running the `Fortran Vectorization` sample - -### Step1 Establishing a Performance Baseline - -To set a performance baseline for the improvements that follow in this sample, compile your sources from the src directory with these compiler options: - - ifort -real-size 64 -O1 matvec.f90 driver.f90 -o MatVector - -Execute 'MatVector' - - ./MatVector -and record the execution time reported in the output. This is the baseline against which subsequent improvements will be measured. - - -### Step 2 Generating a Vectorization Report - -A vectorization report shows what loops in your code were vectorized and explains why other loops were not vectorized. To generate a vectorization report, use the **qopt-report-phase=vec** compiler options together with **qopt-report=1** or **qopt-report=2**. - -Together with **qopt-report-phase=vec**, **qopt-report=1** generates a report with the loops in your code that were vectorized while **qopt-report-phase=vec** with **qopt-report=2** generates a report with both the loops in your code that were vectorized and the reason that other loops were not vectorized. - -Because vectorization is turned off with the **O1** option, the compiler does not generate a vectorization report. To generate a vectorization report, compile your project with the **O2**, **qopt-report-phase=vec**, **qopt-report=1** options: - - ifort -real-size 64 -O2 -qopt-report=1 -qopt-report-phase=vec matvec.f90 driver.f90 -o MatVector - -Recompile the program and then execute MatVector. Record the new execution time. The reduction in time is mostly due to auto-vectorization of the inner loop at line 32 noted in the vectorization report **matvec.optrpt** : - - Begin optimization report for: matvec_ - - Report from: Vector optimizations [vec] - - - LOOP BEGIN at matvec.f90(26,3) - remark #25460: No loop optimizations reported - - LOOP BEGIN at matvec.f90(26,3) - remark #15300: LOOP WAS VECTORIZED - LOOP END - - LOOP BEGIN at matvec.f90(26,3) - - LOOP END - LOOP END - - LOOP BEGIN at matvec.f90(27,3) - remark #25460: No loop optimizations reported - - LOOP BEGIN at matvec.f90(32,6) - - LOOP END - - LOOP BEGIN at matvec.f90(32,6) - remark #15300: LOOP WAS VECTORIZED - LOOP END - - LOOP BEGIN at matvec.f90(32,6) - - LOOP END - - LOOP BEGIN at matvec.f90(32,6) - - LOOP END - LOOP END - -Note - -Your line and column numbers may be different. - -**qopt-report=2** with **qopt-report-phase=vec,loop** returns a list that also includes loops that were not vectorized or multi-versioned, along with the reason that the compiler did not vectorize them or multi-version the loop. - -Recompile your project with the **qopt-report=2** and **qopt-report-phase=vec,loop** options. - - ifort -real-size 64 -O2 -qopt-report-phase=vec -qopt-report=2 matvec.f90 driver.f90 -o MatVector - -The vectorization report matvec.optrpt indicates that the loop at line 33 in matvec.f90 did not vectorize because it is not the innermost loop of the loop nest. - - LOOP BEGIN at matvec.f90(27,3) - remark #15542: loop was not vectorized: inner loop was already vectorized - - LOOP BEGIN at matvec.f90(32,6) - - LOOP END - - LOOP BEGIN at matvec.f90(32,6) - remark #15300: LOOP WAS VECTORIZED - LOOP END - - LOOP BEGIN at matvec.f90(32,6) - - LOOP END - - LOOP BEGIN at matvec.f90(32,6) - - remark #15335: remainder loop was not vectorized: vectorization possible but seems inefficient. Use vector always directive or -vec-threshold0 to override - LOOP END - LOOP END - -Note: Your line and column numbers may be different. - -For more information on the **qopt-report** and **qopt-report-phase** compiler options, see the -[Compiler Options section][3] in the Intel® Fortran Compiler Developer Guide and Reference. -[3]: https://software.intel.com/content/www/us/en/develop/documentation/fortran-compiler-developer-guide-and-reference/top/compiler-reference/compiler-options/alphabetical-list-of-compiler-options.html "Options" - - -### Step 3 Improving Performance by Aligning Data - -The vectorizer can generate faster code when operating on aligned data. In this activity you will improve the vectorizer performance by aligning the arrays a, b, and c in **driver.f90** on a 16-byte boundary so the vectorizer can use aligned load instructions for all arrays rather than the slower unaligned load instructions and can avoid runtime tests of alignment. Using the ALIGNED macro will insert an alignment directive for a, b, and c in driver.f90 with the following syntax: - - !dir$ attributes align : 16 :: a,b,c - -This instructs the compiler to create arrays that it are aligned on a 16-byte boundary, which should facilitate the use of SSE aligned load instructions. - -In addition, the column height of the matrix a needs to be padded out to be a multiple of 16 bytes, so that each individual column of a maintains the same 16-byte alignment. In practice, maintaining a constant alignment between columns is much more important than aligning the start of the arrays. - -To derive the maximum benefit from this alignment, we also need to tell the vectorizer it can safely assume that the arrays in matvec.f90 are aligned by using the directive - - !dir$ vector aligned - -Note If you use **!dir$ vector aligned**, you must be sure that all the arrays or subarrays in the loop are 16-byte aligned. Otherwise, you may get a runtime error. Aligning data may still give a performance benefit even if **!dir$ vector aligned** is not used. See the code under the ALIGNED macro in **matvec.f90** - -If your compilation targets the Intel® AVX-512 instruction set, you should try to align data on a 64-byte boundary. This may result in improved performance. In this case, **!dir$ vector aligned** advises the compiler that the data is 64-byte aligned. - -Recompile the program after adding the ALIGNED macro to ensure consistently aligned data: - - ifort -real-size 64 -qopt-report=2 -qopt-report-phase=vec -D ALIGNED matvec.f90 driver.f90 -o MatVector - - -### Step 4 Improving Performance with Interprocedural Optimization - -The compiler may be able to perform additional optimizations if it is able to optimize across source line boundaries. These may include, but are not limited to, function inlining. This is enabled with the **-ipo** option. - -Recompile the program using the **-ipo** option to enable interprocedural optimization. - - ifort -real-size 64 -qopt-report=2 -qopt-report-phase=vec -D ALIGNED -ipo matvec.f90 driver.f90 -o MatVector - -Note that the vectorization messages now appear at the point of inlining in **driver.f90** (line 70) and this is found in the file **ipo_out.optrpt**. - - LOOP BEGIN at driver.f90(73,16) - remark #15541: loop was not vectorized: inner loop was already vectorized - - LOOP BEGIN at matvec.f90(32,3) inlined into driver.f90(70,14) - remark #15398: loop was not vectorized: loop was transformed to memset or memcpy - LOOP END - - LOOP BEGIN at matvec.f90(33,3) inlined into driver.f90(70,14) - remark #15541: loop was not vectorized: inner loop was already vectorized - - LOOP BEGIN at matvec.f90(38,6) inlined into driver.f90(70,14) - remark #15399: vectorization support: unroll factor set to 4 - remark #15300: LOOP WAS VECTORIZED - LOOP END - LOOP END - LOOP END - - -Note: Your line and column numbers may be different. - -Now, run the executable and record the execution time. - -### Additional Exercises - -The previous examples made use of double precision arrays. They may be built instead with single precision arrays by changing the command-line option **-real-size 64** to **-real-size 32**. The non-vectorized versions of the loop execute only slightly faster the double precision version; however, the vectorized versions are substantially faster. This is because a packed SIMD instruction operating on a 32-byte vector register operates on eight single precision data elements at once instead of four double precision data elements. - -Note: In the example with data alignment, you will need to set ROWBUF=3 to ensure 16-byte alignment for each row of the matrix a. Otherwise, the directive **!dir$ vector aligned** will cause the program to fail. - -This completes the sample that shows how the compiler can optimize performance with various vectorization techniques. - diff --git a/DirectProgramming/Fortran/vec_samples/sample.json b/DirectProgramming/Fortran/vec_samples/sample.json deleted file mode 100644 index c25dc42d09..0000000000 --- a/DirectProgramming/Fortran/vec_samples/sample.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "vec_samples", - "categories": [ "Toolkit/Intel® oneAPI HPC Toolkit" ], - "description": "Fortran Tutorial - Using Auto Vectorization", - "toolchain": [ "ifort" ], - "languages": [ { "fortran": {} } ], - "targetDevice": [ "CPU" ], - "os": [ "darwin" ], - "builder": [ "make" ], - "ciTests":{ - "darwin": [ - { - "id": "fort_vecsample_cpu", - "steps": [ - "make", - "make run", - "make clean" - ] - } - ] - } -} diff --git a/DirectProgramming/Fortran/vec_samples/src/driver.f90 b/DirectProgramming/Fortran/vec_samples/src/driver.f90 deleted file mode 100644 index d4e24e6d71..0000000000 --- a/DirectProgramming/Fortran/vec_samples/src/driver.f90 +++ /dev/null @@ -1,69 +0,0 @@ -! ============================================================== -! Copyright © 2020 Intel Corporation -! -! SPDX-License-Identifier: MIT -! ============================================================= -! -! Part of the vec_samples tutorial. For information, please read -! Tutorial: Auto-vectorization in the Getting Started Tutorials document -! - - -program driver - implicit none - - integer, parameter :: ROW=101 - integer, parameter :: COL=101 - -! Using ROWBUF=3 makes each column of 'a' be aligned at 16-byte intervals by -! adding three elements of padding to each column. - -!DIR$ IF DEFINED(ALIGNED) - integer, parameter :: ROWBUF=3 -!DIR$ ELSE - integer, parameter :: ROWBUF=0 -!DIR$ END IF - - integer, parameter :: TOTROW = ROW + ROWBUF - integer, parameter :: REPEATNTIMES = 1000000 - - integer :: i, j - integer :: size1=TOTROW, size2=COL - real, dimension(TOTROW,COL) :: a - real, dimension(COL) :: b - real, dimension(TOTROW) :: c - real :: sum - real(8) :: cptim1, cptim2 - -!DIR$ IF DEFINED(ALIGNED) -! aligning the start of each array is unimportant in this simple example. -! preserving the same alignment for all rows of the matrix is much more important. -!DIR$ attributes align : 32 :: a,b,c -!DIR$ ENDIF - -! initialize the matrix and vector - - a = reshape( (/((mod(i*j+1,10), i=0,size1-1), j=0,size2-1)/), & -& (/size1, size2/) ) - b = (/(mod(j+3,10), j=0,size2-1)/) - - if(ROWBUF.gt.0) a(ROW+1:TOTROW,:) = 0. - -! initialize timing - call cpu_time(cptim1) - -! just do it - do i=1,REPEATNTIMES - call matvec(size1, size2, a, b, c) -! this line so that each iteration is different, so that -! the compiler can't optimize away every iteration except one. - b(1) = b(1) + 0.000001 - enddo - -! print cpu time taken and a simple checksum -! (use a different timer for threaded programs) - call cpu_time(cptim2) - print '(''time taken '',f8.3,'' sum='',6pe20.12/)', & -& (cptim2 - cptim1), sum(c) - - end program driver diff --git a/DirectProgramming/Fortran/vec_samples/src/matvec.f90 b/DirectProgramming/Fortran/vec_samples/src/matvec.f90 deleted file mode 100644 index 56ab6da14f..0000000000 --- a/DirectProgramming/Fortran/vec_samples/src/matvec.f90 +++ /dev/null @@ -1,30 +0,0 @@ -! ============================================================== -! Copyright © 2020 Intel Corporation -! -! SPDX-License-Identifier: MIT -! ============================================================= -! -! Part of the vec_samples tutorial. For information, please read -! Tutorial: Auto-vectorization in the Getting Started Tutorials document -! - -subroutine matvec(size1,size2,a,b,c) - implicit none - integer, intent(in) :: size1,size2 - real, dimension(size1,size2), intent(in) :: a - real, dimension(size2), intent(in) :: b - real, dimension(size1), intent(out) :: c - integer :: i,j,k - - c=0. - do j=1,size2 - -!DIR$ IF DEFINED(ALIGNED) -!DIR$ vector aligned -!DIR$ END IF - do i=1,size1 - c(i) = c(i) + a(i,j) * b(j) - enddo - enddo - -end subroutine matvec From c5c3880c7ea6da5ecc2d1773ff1f61bcae293345 Mon Sep 17 00:00:00 2001 From: JoeOster <52936608+JoeOster@users.noreply.github.com> Date: Wed, 26 Aug 2020 13:15:22 -0700 Subject: [PATCH 007/121] Update Makefile.win changing compiler name from "dpcpp-cl" to "dpcpp" --- .../DPC++/DenseLinearAlgebra/matrix_mul/Makefile.win | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DirectProgramming/DPC++/DenseLinearAlgebra/matrix_mul/Makefile.win b/DirectProgramming/DPC++/DenseLinearAlgebra/matrix_mul/Makefile.win index 7db1a6f21f..3b63bd1379 100644 --- a/DirectProgramming/DPC++/DenseLinearAlgebra/matrix_mul/Makefile.win +++ b/DirectProgramming/DPC++/DenseLinearAlgebra/matrix_mul/Makefile.win @@ -1,4 +1,4 @@ -DPCPP_CXX = dpcpp-cl +DPCPP_CXX = dpcpp DPCPP_CXXFLAGS = /Zi /EHsc DPCPP_LDFLAGS = DPCPP_EXE_NAME = matrix_mul_dpcpp.exe From 0ead4599368accf4fe5fb7827b8e05331ba0b9d7 Mon Sep 17 00:00:00 2001 From: JoeOster <52936608+JoeOster@users.noreply.github.com> Date: Wed, 26 Aug 2020 13:17:30 -0700 Subject: [PATCH 008/121] Update Makefile.win --- .../DPC++/DenseLinearAlgebra/simple-add/Makefile.win | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DirectProgramming/DPC++/DenseLinearAlgebra/simple-add/Makefile.win b/DirectProgramming/DPC++/DenseLinearAlgebra/simple-add/Makefile.win index d59ec56431..1416d8759a 100644 --- a/DirectProgramming/DPC++/DenseLinearAlgebra/simple-add/Makefile.win +++ b/DirectProgramming/DPC++/DenseLinearAlgebra/simple-add/Makefile.win @@ -1,4 +1,4 @@ -CXX = dpcpp-cl +CXX = dpcpp CXXFLAGS = -O2 -EHsc -Zi EXE_NAME = simple-add-usm.exe From d024a8efe92ce23c7ca65d4448f37ec4b08fee4b Mon Sep 17 00:00:00 2001 From: JoeOster <52936608+JoeOster@users.noreply.github.com> Date: Wed, 26 Aug 2020 13:18:33 -0700 Subject: [PATCH 009/121] Update Makefile.win.fpga --- .../DPC++/DenseLinearAlgebra/simple-add/Makefile.win.fpga | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DirectProgramming/DPC++/DenseLinearAlgebra/simple-add/Makefile.win.fpga b/DirectProgramming/DPC++/DenseLinearAlgebra/simple-add/Makefile.win.fpga index c77f1c19a3..d83011db10 100644 --- a/DirectProgramming/DPC++/DenseLinearAlgebra/simple-add/Makefile.win.fpga +++ b/DirectProgramming/DPC++/DenseLinearAlgebra/simple-add/Makefile.win.fpga @@ -1,4 +1,4 @@ -CXX = dpcpp-cl +CXX = dpcpp CXXFLAGS = -O2 -EHsc -Zi LDFLAGS = From d5ce16c8017067cf1b4e341d00aacc6ff7f70c23 Mon Sep 17 00:00:00 2001 From: JoeOster <52936608+JoeOster@users.noreply.github.com> Date: Thu, 27 Aug 2020 11:43:57 -0700 Subject: [PATCH 010/121] Update CMakeLists.txt --- Libraries/oneDNN/dpcpp_interoperability/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Libraries/oneDNN/dpcpp_interoperability/CMakeLists.txt b/Libraries/oneDNN/dpcpp_interoperability/CMakeLists.txt index 4327bfb627..5c397848cb 100644 --- a/Libraries/oneDNN/dpcpp_interoperability/CMakeLists.txt +++ b/Libraries/oneDNN/dpcpp_interoperability/CMakeLists.txt @@ -1,6 +1,5 @@ cmake_minimum_required(VERSION 2.8.11) if("${CMAKE_CXX_COMPILER}" STREQUAL "") - set(CMAKE_C_COMPILER "clang") set(CMAKE_CXX_COMPILER "dpcpp") endif() project (dpcpp_interoperability) From a8f34a5255e5c550d5bc2d73da0d5e49aeeecf83 Mon Sep 17 00:00:00 2001 From: JoeOster <52936608+JoeOster@users.noreply.github.com> Date: Thu, 27 Aug 2020 11:45:48 -0700 Subject: [PATCH 011/121] Update CMakeLists.txt --- Libraries/oneDNN/getting_started/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Libraries/oneDNN/getting_started/CMakeLists.txt b/Libraries/oneDNN/getting_started/CMakeLists.txt index efbdd1aba1..6cf97649a3 100644 --- a/Libraries/oneDNN/getting_started/CMakeLists.txt +++ b/Libraries/oneDNN/getting_started/CMakeLists.txt @@ -1,6 +1,5 @@ cmake_minimum_required(VERSION 2.8.11) if("${CMAKE_CXX_COMPILER}" STREQUAL "") - set(CMAKE_C_COMPILER "clang") set(CMAKE_CXX_COMPILER "dpcpp") endif() project (getting_started) From d1d4a6b3d51dd5faffdbe1172c7fc4173c8c1b3e Mon Sep 17 00:00:00 2001 From: JoeOster <52936608+JoeOster@users.noreply.github.com> Date: Thu, 27 Aug 2020 11:46:36 -0700 Subject: [PATCH 012/121] Update CMakeLists.txt --- Libraries/oneDNN/simple_model/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Libraries/oneDNN/simple_model/CMakeLists.txt b/Libraries/oneDNN/simple_model/CMakeLists.txt index 82baa34153..90d3c95cd5 100644 --- a/Libraries/oneDNN/simple_model/CMakeLists.txt +++ b/Libraries/oneDNN/simple_model/CMakeLists.txt @@ -1,6 +1,5 @@ cmake_minimum_required(VERSION 2.8.11) if("${CMAKE_CXX_COMPILER}" STREQUAL "") - set(CMAKE_C_COMPILER "clang") set(CMAKE_CXX_COMPILER "dpcpp") endif() project (simple_model) From 828111cc65434a4aff20ae990428abfec4b2ef46 Mon Sep 17 00:00:00 2001 From: JoeOster <52936608+JoeOster@users.noreply.github.com> Date: Tue, 15 Sep 2020 11:26:54 -0700 Subject: [PATCH 013/121] Update README.md --- .../DPC++/ParallelPatterns/dpc_reduce/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/DirectProgramming/DPC++/ParallelPatterns/dpc_reduce/README.md b/DirectProgramming/DPC++/ParallelPatterns/dpc_reduce/README.md index ca20f04511..a67a28da94 100644 --- a/DirectProgramming/DPC++/ParallelPatterns/dpc_reduce/README.md +++ b/DirectProgramming/DPC++/ParallelPatterns/dpc_reduce/README.md @@ -84,16 +84,28 @@ where ### Example of Output Rank #0 runs on: lqnguyen-NUC1, uses device: Intel(R) Gen9 HD Graphics NEO + Number of steps is 1000000 + Cpu Seq calc: PI =3.14 in 0.00422 seconds + Cpu TBB calc: PI =3.14 in 0.00177 seconds + dpstd native: PI =3.14 in 0.209 seconds + dpstd native2: PI =3.14 in 0.213 seconds + dpstd native3: PI =3.14 in 0.00222 seconds + dpstd native4: PI =3.14 in 0.00237 seconds + dpstd two steps: PI =3.14 in 0.0014 seconds + dpstd transform_reduce: PI =3.14 in 0.000528 seconds + mpi native: PI =3.14 in 0.548 seconds + mpi transform_reduce: PI =3.14 in 0.000498 seconds + succes From 801a485c8b5ffcf0684aef34caef4623f042f967 Mon Sep 17 00:00:00 2001 From: JoeOster <52936608+JoeOster@users.noreply.github.com> Date: Tue, 15 Sep 2020 11:35:22 -0700 Subject: [PATCH 014/121] Update README.md --- .../ParallelPatterns/dpc_reduce/README.md | 41 +++++++------------ 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/DirectProgramming/DPC++/ParallelPatterns/dpc_reduce/README.md b/DirectProgramming/DPC++/ParallelPatterns/dpc_reduce/README.md index a67a28da94..9668b00346 100644 --- a/DirectProgramming/DPC++/ParallelPatterns/dpc_reduce/README.md +++ b/DirectProgramming/DPC++/ParallelPatterns/dpc_reduce/README.md @@ -83,29 +83,18 @@ where ### Example of Output -Rank #0 runs on: lqnguyen-NUC1, uses device: Intel(R) Gen9 HD Graphics NEO - -Number of steps is 1000000 - -Cpu Seq calc: PI =3.14 in 0.00422 seconds - -Cpu TBB calc: PI =3.14 in 0.00177 seconds - -dpstd native: PI =3.14 in 0.209 seconds - -dpstd native2: PI =3.14 in 0.213 seconds - -dpstd native3: PI =3.14 in 0.00222 seconds - -dpstd native4: PI =3.14 in 0.00237 seconds - -dpstd two steps: PI =3.14 in 0.0014 seconds - -dpstd transform_reduce: PI =3.14 in 0.000528 seconds - -mpi native: PI =3.14 in 0.548 seconds - -mpi transform_reduce: PI =3.14 in 0.000498 seconds - -succes - +```c++ +Rank #0 runs on: lqnguyen-NUC1, uses device: Intel(R) Gen9 HD Graphics NEO \ +Number of steps is 1000000 \ +Cpu Seq calc: PI =3.14 in 0.00422 seconds \ +Cpu TBB calc: PI =3.14 in 0.00177 seconds \ +dpstd native: PI =3.14 in 0.209 seconds \ +dpstd native2: PI =3.14 in 0.213 seconds \ +dpstd native3: PI =3.14 in 0.00222 seconds \ +dpstd native4: PI =3.14 in 0.00237 seconds \ +dpstd two steps: PI =3.14 in 0.0014 seconds \ +dpstd transform_reduce: PI =3.14 in 0.000528 seconds \ +mpi native: PI =3.14 in 0.548 seconds \ +mpi transform_reduce: PI =3.14 in 0.000498 seconds \ +succes \ +``` From 357d49b1874b104d20a239e27d15dc064f981efd Mon Sep 17 00:00:00 2001 From: JoeOster <52936608+JoeOster@users.noreply.github.com> Date: Mon, 5 Oct 2020 09:10:27 -0700 Subject: [PATCH 015/121] Update from Legal Approval of 10/05/2020 --- third-party-programs.txt | 127 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/third-party-programs.txt b/third-party-programs.txt index 3748649379..17baff362f 100644 --- a/third-party-programs.txt +++ b/third-party-programs.txt @@ -226,6 +226,133 @@ Each version is given a distinguishing version number. If the Library as you rec If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. +-------------------------------------------------------------------------------- +8. Rodinia + +LICENSE TERMS + +Copyright (c)2008-2011 University of Virginia +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted without royalty fees or other restrictions, provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of the University of Virginia, the Dept. of Computer Science, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF VIRGINIA OR THE SOFTWARE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +If you use this software or a modified version of it, please cite the most relevant among the following papers: + + - M. A. Goodrum, M. J. Trotter, A. Aksel, S. T. Acton, and K. Skadron. Parallelization of Particle Filter Algorithms. In Proceedings of the 3rd Workshop on Emerging Applications and Many-core Architecture (EAMA), in conjunction with the IEEE/ACM International +Symposium on Computer Architecture (ISCA), June 2010. + + - S. Che, M. Boyer, J. Meng, D. Tarjan, J. W. Sheaffer, Sang-Ha Lee and K. Skadron. +Rodinia: A Benchmark Suite for Heterogeneous Computing. IEEE International Symposium +on Workload Characterization, Oct 2009. + +- J. Meng and K. Skadron. "Performance Modeling and Automatic Ghost Zone Optimization +for Iterative Stencil Loops on GPUs." In Proceedings of the 23rd Annual ACM International +Conference on Supercomputing (ICS), June 2009. + +- L.G. Szafaryn, K. Skadron and J. Saucerman. "Experiences Accelerating MATLAB Systems +Biology Applications." in Workshop on Biomedicine in Computing (BiC) at the International +Symposium on Computer Architecture (ISCA), June 2009. + +- M. Boyer, D. Tarjan, S. T. Acton, and K. Skadron. "Accelerating Leukocyte Tracking using CUDA: +A Case Study in Leveraging Manycore Coprocessors." In Proceedings of the International Parallel +and Distributed Processing Symposium (IPDPS), May 2009. + +- S. Che, M. Boyer, J. Meng, D. Tarjan, J. W. Sheaffer, and K. Skadron. "A Performance +Study of General Purpose Applications on Graphics Processors using CUDA" Journal of +Parallel and Distributed Computing, Elsevier, June 2008. + + +--------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- +11. psutil + +BSD 3-Clause License + +Copyright (c) 2009, Jay Loden, Dave Daeschler, Giampaolo Rodola' +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of the psutil authors nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +-------------------------------------------------------------------------------- + +9. SDL2 + +SDL 2.0 and newer are available under the zlib license : + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. + + +-------------------------------------------------------------------------------- + +10. Plotly.js + +The MIT License (MIT) + +Copyright (c) 2020 Plotly, Inc + +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. + -------------------------------------------------------------------------------- Other names and brands may be claimed as the property of others. + From 0f5032fbc2dae9a106ad5aadb465a83bb986451e Mon Sep 17 00:00:00 2001 From: JoeOster <52936608+JoeOster@users.noreply.github.com> Date: Tue, 6 Oct 2020 12:41:22 -0700 Subject: [PATCH 016/121] Create README.md --- .github/images/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/images/README.md diff --git a/.github/images/README.md b/.github/images/README.md new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/.github/images/README.md @@ -0,0 +1 @@ + From a6437599242d3c273eaaadeadfc327bce13ffb33 Mon Sep 17 00:00:00 2001 From: JoeOster <52936608+JoeOster@users.noreply.github.com> Date: Tue, 6 Oct 2020 12:41:48 -0700 Subject: [PATCH 017/121] Add files via upload --- .github/images/FileStructure.png | Bin 0 -> 108144 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .github/images/FileStructure.png diff --git a/.github/images/FileStructure.png b/.github/images/FileStructure.png new file mode 100644 index 0000000000000000000000000000000000000000..d7b9f3680901a48687c2904cc6e03778bcdc14f2 GIT binary patch literal 108144 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 literal 0 HcmV?d00001 From b10f0adb71bd2cc0f67ea0e8d1af309a4bc23f62 Mon Sep 17 00:00:00 2001 From: tomlenth Date: Wed, 7 Oct 2020 11:35:19 -0700 Subject: [PATCH 018/121] Update README.md minor modifications to content, purpose and key implementation details. --- .../all-pairs-shortest-paths/README.md | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/DirectProgramming/DPC++/GraphAlgorithms/all-pairs-shortest-paths/README.md b/DirectProgramming/DPC++/GraphAlgorithms/all-pairs-shortest-paths/README.md index 23db7ecd8a..ade650a2d2 100644 --- a/DirectProgramming/DPC++/GraphAlgorithms/all-pairs-shortest-paths/README.md +++ b/DirectProgramming/DPC++/GraphAlgorithms/all-pairs-shortest-paths/README.md @@ -1,5 +1,5 @@ # All Pairs Shortest Paths sample -`All Pairs Shortest Paths` uses the Floyd Warshall algorithm to find the shortest paths between pairs of vertices in a graph. It uses a parallel blocked algorithm that enables the application to efficiently offload compute intensive work to the GPU. +`All Pairs Shortest Paths` uses the Floyd-Warshall algorithm to find the shortest paths between pairs of vertices in a graph. It uses a parallel blocked algorithm that enables the application to efficiently offload compute intensive work to the GPU. For comprehensive instructions regarding DPC++ Programming, go to https://software.intel.com/en-us/oneapi-programming-guide and search based on relevant terms noted in the comments. @@ -11,23 +11,27 @@ For comprehensive instructions regarding DPC++ Programming, go to https://softwa | What you will learn | The All Pairs Shortest Paths sample demonstrates the following using the Intel® oneAPI DPC++/C++ Compiler
  • Offloading compute intensive parts of the application using lambda kernel
  • Measuring kernel execution time
| Time to complete | 15 minutes -## Purpose -This sample uses blocked Floyd-Warshall all pairs shortest paths algorithm to compute a matrix that represents the minimum distance from any node to all other nodes in the graph. Using parallel blocked processing, blocks can be calculated simultaneously by distributing task computations to the GPU. -## Key implementation details -The basic DPC++ implementation explained in the code includes device selector, unified shared memory, kernel, and command groups. +## Purpose +This sample uses blocked Floyd-Warshall all pairs shortest paths algorithm to compute a matrix that represents the minimum distance from any node to all other nodes in the graph. Using parallel blocked processing, blocks can be calculated simultaneously by distributing task computations to the GPU. For comparison, the application is run sequentially and parallel with run times for each displayed in the application's output. The device where the code us run is also identified. -The parallel implementation of blocked Floyd Warshall algorithm has three phases. Given a prior round of these computation phases are complete, phase 1 is independent; Phase 2 can only execute after phase 1 completes; Similarly phase 3 depends on phase 2 so can only execute after phase 2 is complete. +The parallel implementation of blocked Floyd-Warshall algorithm has three phases. Given a prior round of these computation phases are complete, phase 1 is independent; Phase 2 can only execute after phase 1 completes; Similarly phase 3 depends on phase 2 so can only execute after phase 2 is complete. The inner loop of the sequential implementation is: g[i][j] = min(g[i][j], g[i][k] + g[k][j]) -A careful observation shows that for the kth iteration of the outer loop, the computation depends on cells either on the kth column, g[i][k] or on the kth row, g[k][j] of the graph. Phase 1 handles g[k][k], phase 2 handles g[\*][k] and g[k][\*], and phase 3 handles g[\*][\*] in that sequence. This cell level observations largely propagate to the blocks as well. +A careful observation shows that for the kth iteration of the outer loop, the computation depends on cells either on the kth column, g[i][k] or on the kth row, g[k][j] of the graph. Phase 1 handles g[k][k], phase 2 handles g[\*][k] and g[k][\*], and phase 3 handles g[\*][\*] in that sequence. This cell level observations largely propagate to the blocks as well. + +In each phase computation within a block can proceed independently in parallel. + + +## Key implementation details +Includes device selector, unified shared memory, kernel, and command groups in order to implement a solution using parallel block method targeting the GPU. -In each phase computation within a block can proceed independently in parallel. ## License -This code sample is licensed under MIT license +This code sample is licensed under MIT license. + ## Building the Program for CPU and GPU @@ -61,6 +65,7 @@ Perform the following steps: * Build the program using VS2017 or VS2019: Right click on the solution file and open using either VS2017 or VS2019 IDE. Right click on the project in Solution explorer and select Rebuild. From top menu select Debug -> Start without Debugging. * Build the program using MSBuild: Open "x64 Native Tools Command Prompt for VS2017" or "x64 Native Tools Command Prompt for VS2019". Run - MSBuild all-pairs-shortest-paths.sln /t:Rebuild /p:Configuration="Release" + ## Running the sample ### Example Output From 1a68b03c269b16fdcae599bb5fb653cbd31f1d79 Mon Sep 17 00:00:00 2001 From: tomlenth Date: Wed, 7 Oct 2020 11:37:22 -0700 Subject: [PATCH 019/121] Update sample.json aligned description with readme --- .../DPC++/GraphAlgorithms/all-pairs-shortest-paths/sample.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DirectProgramming/DPC++/GraphAlgorithms/all-pairs-shortest-paths/sample.json b/DirectProgramming/DPC++/GraphAlgorithms/all-pairs-shortest-paths/sample.json index 62c939ead1..0b48c4bf1d 100644 --- a/DirectProgramming/DPC++/GraphAlgorithms/all-pairs-shortest-paths/sample.json +++ b/DirectProgramming/DPC++/GraphAlgorithms/all-pairs-shortest-paths/sample.json @@ -2,7 +2,7 @@ "guid": "4F0F5FBD-C237-4A9F-B259-2C56ABFB40D9", "name": "all-pairs-shortest-paths", "categories": [ "Toolkit/Intel® oneAPI Base Toolkit/oneAPI DPC++/C++ Compiler/CPU and GPU" ], - "description": "all-pairs-shortest-paths using Intel® oneAPI DPC++ Language", + "description": "All Pairs Shortest Paths uses finds the shortest paths between pairs of vertices in a graph using a parallel blocked algorithm that enables the application to efficiently offload compute intensive work to the GPU.", "toolchain": [ "dpcpp" ], "targetDevice": [ "CPU", "GPU" ], "languages": [ { "cpp": {} } ], From 630bfb48d0b7827bbd47000a2ef3555a8f27fb02 Mon Sep 17 00:00:00 2001 From: tomlenth Date: Wed, 7 Oct 2020 13:30:26 -0700 Subject: [PATCH 020/121] Update README.md reshuffled parts of the purpose and implementation details and abstracted a few key concepts into better summaries. --- .../DPC++/SparseLinearAlgebra/merge-spmv/README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/DirectProgramming/DPC++/SparseLinearAlgebra/merge-spmv/README.md b/DirectProgramming/DPC++/SparseLinearAlgebra/merge-spmv/README.md index c1c06face0..8441c17e98 100644 --- a/DirectProgramming/DPC++/SparseLinearAlgebra/merge-spmv/README.md +++ b/DirectProgramming/DPC++/SparseLinearAlgebra/merge-spmv/README.md @@ -11,11 +11,11 @@ For comprehensive instructions regarding DPC++ Programming, go to https://softwa | What you will learn | The Sparse Matrix Vector sample demonstrates the following using the Intel® oneAPI DPC++/C++ Compiler
  • Offloading compute intensive parts of the application using lambda kernel
  • Measuring kernel execution time
| Time to complete | 15 minutes + ## Purpose -Sparse linear algebra algorithms are common in HPC, in fields as machine learning and computational science. In this sample, a merge based sparse matrix and vector multiplication algorithm is implemented. The input matrix is in compressed sparse row format. Use a parallel merge model enables the application to efficiently offload compute intensive operation to the GPU. +Sparse linear algebra algorithms are common in HPC, in fields as machine learning and computational science. In this sample, a merge based sparse matrix and vector multiplication algorithm is implemented. The input matrix is in compressed sparse row format. Use a parallel merge model enables the application to efficiently offload compute intensive operation to the GPU. For comparison, the application is run sequentially and parallel with run times for each displayed in the application's output. The device where the code us run is also identified. -## Key implementation details -The basic DPC++ implementation explained in the code includes device selector, unified shared memory, kernel, and command groups. +The workgroup size requirement is 256. If your hardware cannot support this, the application will present an error. Compressed Sparse Row (CSR) representation for sparse matrix have three components: