diff --git a/ci/cuda_nvidia/README.md b/ci/cuda_nvidia/README.md new file mode 100644 index 00000000000..68b351fd850 --- /dev/null +++ b/ci/cuda_nvidia/README.md @@ -0,0 +1,153 @@ +# Running LFortran's CUDA backend on NVIDIA hardware + +This directory holds the recipe used to validate `--gpu=cuda` on a real NVIDIA +GPU: LFortran's own GPU integration tests, and the BerkeleyLab +[Formal](https://github.com/BerkeleyLab/formal) library and its 2D +advection-diffusion example. `run_formal_cuda.sh` performs every step below and +prints a summary; the sections explain what it does and how to run the pieces +by hand. + +Validated on: NVIDIA RTX PRO 6000 Blackwell Server Edition (compute capability +12.0, `sm_120`), driver 610.43.02, CUDA 13.3 (`/usr/local/cuda`), Ubuntu 24.04, +Pixi `llvm11` environment (LLVM 11.1.0, conda-forge GCC 15.3 as nvcc's host +compiler). + +## Prerequisites + +- An NVIDIA driver and a CUDA toolkit with `nvcc` on `PATH` + (`export PATH=/usr/local/cuda/bin:$PATH`). `cuobjdump`, `nsys` and + `compute-sanitizer` from the same toolkit are used for evidence when present. +- Git and [Pixi](https://pixi.sh). Everything else (LLVM 11, the host C/C++ + compilers, FPM, GFortran 16) comes from Pixi environments. +- If `pixi shell` does not work in your shell, prefix commands with + `eval "$(pixi shell-hook -e llvm11)"` or use `pixi run -e llvm11 ...`. + +## 1. Build LFortran + +From the root of this checkout: + +```bash +CMAKE_BUILD_PARALLEL_LEVEL=16 pixi run -e llvm11 build \ + '-DCMAKE_CXX_FLAGS_DEBUG=-g -O2' '-DCMAKE_C_FLAGS_DEBUG=-g -O2' > build.log 2>&1 +pixi run -e llvm11 bash -c 'command -v lfortran; lfortran --version; command -v nvcc' +``` + +`lfortran` must resolve to `build/llvm11/src/bin/lfortran` of this checkout. + +## 2. Quick check + +```bash +cat > saxpy.f90 <<'EOF' +program saxpy +implicit none +integer, parameter :: n = 10000000 +real, allocatable :: x(:), y(:) +real :: a +integer :: i +allocate(x(n), y(n)) +a = 2.0; x = 1.0; y = 3.0 +do concurrent (i = 1:n) + y(i) = a*x(i) + y(i) +end do +if (abs(y(1) - 5.0) > 1e-6 .or. abs(y(n) - 5.0) > 1e-6) error stop "wrong result" +print *, "OK" +end program +EOF +pixi run -e llvm11 lfortran --gpu=cuda saxpy.f90 -o saxpy_gpu +CUDA_DISABLE_PTX_JIT=1 ./saxpy_gpu # prints OK +cuobjdump --list-elf --list-ptx saxpy_gpu # sm_120 cubins on this GPU +``` + +GPU options: + +- `--gpu=cuda` compiles the device code with nvcc and runs it on the GPU. + `--gpu=cuda_cpu` compiles the same device code as host C++ and runs it on + the CPU (no GPU needed; this is what CI runs). +- `--gpu-arch=` selects the GPU architecture, e.g. `sm_120`. The default + is `native`, the GPUs of the compiling machine. On a machine without a GPU + nvcc then falls back to its oldest default architecture with a warning, so + pass an explicit architecture when cross-compiling. +- `--device-compiler=` selects nvcc (or, for `cuda_cpu`, the host C++ + compiler). +- `--show-gpu-kernel-source` prints the generated `.cu` source. +- `CUDA_DISABLE_PTX_JIT=1` at run time makes a binary built for the wrong + architecture fail instead of being JIT compiled by the driver. + +## 3. LFortran GPU integration tests on the GPU + +```bash +CUDA_DISABLE_PTX_JIT=1 pixi run -e llvm11 integration_tests -b cuda -j16 > cuda.log 2>&1 +grep 'tests passed' cuda.log +``` + +Every test labeled `cuda_cpu` that passes on a real GPU also carries the `cuda` +label (485 tests on this branch). CI has no NVIDIA GPU and runs only +`-b cuda_cpu`, so run this on GPU machines after changing GPU code. + +## 4. Formal + +```bash +ci/cuda_nvidia/run_formal_cuda.sh /path/to/work-dir > formal.log 2>&1 +tail -40 formal.log +``` + +The script clones Formal at the validated revision (`FORMAL_REF`, the head of +BerkeleyLab/formal#71, which contains #70), then, with logs in +`/logs` and data in `/validation`: + +1. Builds and runs Formal's FPM test suite and both solvers with + `--gpu=cuda_cpu` (expect 32/32 tests, 0 skipped). +2. The same with native `--gpu=cuda --gpu-arch=native` and + `CUDA_DISABLE_PTX_JIT=1`, in a separate build directory. +3. Builds three executables of the example: native GPU, ordinary host LLVM, + and GFortran 16 as an independent oracle. +4. Compares full fields from a shared raw input: + - a 17x13, 9-step Gaussian case, native against host LLVM, with Formal's + `validate_2d_advection_workspace.py`; + - a nonsquare 13x11, 3-step case with nonzero, non-smooth boundaries + (`make_boundary_input.py`), native against GFortran and host LLVM, with + Formal's strict `compare_2d_raw_fields.py` (finite fields, evolution, + unchanged boundaries, default tolerances). +5. Records evidence of native execution: `cuobjdump` of the executable, `nsys` + kernel/transfer summaries, and `compute-sanitizer` memcheck, racecheck, + synccheck and initcheck on both solvers. +6. Runs `integration_tests -b cuda` (step 3 above). + +Environment overrides: `GPU_ARCH` (e.g. `sm_120`), `JOBS`, `FORMAL_REF`, +`SKIP_PROFILE=1`, `SKIP_LFORTRAN_TESTS=1`. + +Notes on the recipe: + +- Keep all Fortran flags in a single FPM `--flag` argument. +- `--input` supplies the grid, step count and time step, so Formal rejects it + together with `--cells`, `--steps` or `--dt`; and only the workspace solver + accepts `--input`. +- `formal/benchmarks/pixi.toml` only lists `osx-arm64`; `fpm/pixi.toml` here + pins the same FPM (0.13.0) for Linux. +- Formal needs GFortran 16 (its README asks for 16.3+); conda-forge's 16.2 + builds it with `-fcoarray=single`. `gfortran16/pixi.toml` provides it. +- `nsys` and `compute-sanitizer` need a writable `TMPDIR`; the script uses + `/tmp` (a shared `/tmp/nvidia` can belong to another user). +- The operators solver cannot read a raw input, so its initial field is + computed by each build. GPU `sinf`/`expf` and the host math libraries round + differently (host LLVM and GFortran differ as well), at the 1e-7 level, so + that path is compared against its own initial state rather than bitwise + across builds. + +## Results on the validation machine + +| Check | Result | +|---|---| +| Formal tests, `cuda_cpu` | 32/32, 0 skipped | +| Formal tests, native CUDA, PTX JIT disabled | 32/32, 0 skipped | +| Embedded device code | `sm_120` cubins only | +| Gaussian 17x13/9, native vs host LLVM | max abs 1.2e-10, relative L2 7.9e-11 | +| Boundary 13x11/3, native vs GFortran 16 vs host LLVM | bitwise identical; boundaries fixed; field evolves | +| compute-sanitizer (4 tools x 2 solvers) | 0 errors | +| nsys, workspace solver | all arithmetic in kernels; transfers constant in the step count | +| `integration_tests -b cuda` | all pass | + +Known limitation: the operators solver runs every kernel on the GPU, but +LFortran synchronizes at each procedure exit and re-uploads data per launch, +and part of its arithmetic is host array expressions, so most of its time is +host work and transfers. The workspace solver is fully device resident. diff --git a/ci/cuda_nvidia/fpm/pixi.toml b/ci/cuda_nvidia/fpm/pixi.toml new file mode 100644 index 00000000000..b34100eee6d --- /dev/null +++ b/ci/cuda_nvidia/fpm/pixi.toml @@ -0,0 +1,8 @@ +[workspace] +name = "formal-fpm-linux" +description = "Linux counterpart of formal/benchmarks/pixi.toml (which only lists osx-arm64): the same pinned FPM" +channels = ["conda-forge"] +platforms = ["linux-64"] + +[dependencies] +fpm = "==0.13.0" diff --git a/ci/cuda_nvidia/gfortran16/pixi.toml b/ci/cuda_nvidia/gfortran16/pixi.toml new file mode 100644 index 00000000000..2ee6bb11409 --- /dev/null +++ b/ci/cuda_nvidia/gfortran16/pixi.toml @@ -0,0 +1,9 @@ +[workspace] +name = "formal-gfortran16" +description = "Independent GFortran oracle for Formal (README asks for GCC >= 16.3; newest on conda-forge is 16.2)" +channels = ["conda-forge"] +platforms = ["linux-64"] + +[dependencies] +gfortran = "16.2.*" +fpm = "==0.13.0" diff --git a/ci/cuda_nvidia/make_boundary_input.py b/ci/cuda_nvidia/make_boundary_input.py new file mode 100644 index 00000000000..221ba043fcb --- /dev/null +++ b/ci/cuda_nvidia/make_boundary_input.py @@ -0,0 +1,21 @@ +"""Write a FADV2D1 raw input with nonzero, non-smooth boundaries on a nonsquare grid.""" +import sys +import numpy as np +out, nx, ny, steps, dt = sys.argv[1], int(sys.argv[2]), int(sys.argv[3]), int(sys.argv[4]), float(sys.argv[5]) +rng = np.random.default_rng(20261019) +X, Y = np.meshgrid(np.linspace(0, 1, nx + 2), np.linspace(0, 1, ny + 2), indexing="ij") +s = (0.5 + 0.3 * np.sin(3.1 * X) * np.cos(2.3 * Y) + 0.05 * rng.standard_normal(X.shape)).astype(np.float32) +s[0, :] = 1.0 + 0.1 * np.arange(ny + 2) # distinct nonzero values on each boundary +s[-1, :] = -0.75 + 0.05 * np.arange(ny + 2) +s[:, 0] = 2.0 - 0.07 * np.arange(nx + 2) +s[:, -1] = 0.3 + 0.11 * np.arange(nx + 2) +u = (0.4 + 0.2 * rng.standard_normal((nx + 1, ny + 2))).astype(np.float32) +v = (-0.3 + 0.2 * rng.standard_normal((nx + 2, ny + 1))).astype(np.float32) +dt32 = np.float32(dt) +with open(out, "wb") as f: + f.write(b"FADV2D1\n") + f.write(f"{nx} {ny} {steps} {float(dt32):.16E}\n".encode()) + f.write(b"mode raw\n") + for a in (s, u, v): + f.write(np.asfortranarray(a).astype(" $name (log: $log)" + "$@" > "$log" 2>&1 + local rc=$? + if [ $rc -eq 0 ]; then SUMMARY+=("PASS $name"); else SUMMARY+=("FAIL $name (exit $rc, $log)"); FAILED=1; fi + return $rc +} +lf() { pixi run --manifest-path "$LFORTRAN_ROOT/pixi.toml" -e llvm11 "$@"; } +formal_fpm() { + lf pixi run --manifest-path "$FPM_MANIFEST" \ + /bin/bash -c 'cd "$FORMAL_ROOT" && exec fpm "$@"' _ "$@" +} + +# 0. Toolchain and revisions. +{ + echo "date: $(date -Is)"; echo "host: $(hostname)" + echo "lfortran_root: $LFORTRAN_ROOT" + echo "lfortran_head: $(git -C "$LFORTRAN_ROOT" rev-parse HEAD)" + nvidia-smi --query-gpu=name,compute_cap,driver_version --format=csv,noheader + nvidia-smi -q | grep -i 'Addressing Mode' + lf bash -c 'command -v lfortran; lfortran --version | head -1; llvm-config --version; + command -v nvcc; nvcc --version | tail -2; command -v c++; c++ --version | head -1' +} > "$LOGS/00-environment.log" 2>&1 +cat "$LOGS/00-environment.log" +test -x "$LFORTRAN_COMPILER" || { echo "Build LFortran first: pixi run -e llvm11 build (see README.md)"; exit 1; } +NVCC="$(lf bash -c 'command -v nvcc' 2>/dev/null)" +CUDA_CPU_CXX="$(lf bash -c 'command -v "${CXX:-c++}"' 2>/dev/null)" +test -x "$NVCC" || { echo "nvcc not found on PATH"; exit 1; } +CUDA_BIN="$(dirname "$NVCC")" + +# 1. Formal at the validated revision. +if [ ! -d "$FORMAL_ROOT/.git" ]; then + git clone -q "$FORMAL_REPO" "$FORMAL_ROOT" +fi +git -C "$FORMAL_ROOT" fetch -q origin "$FORMAL_REF" 2>/dev/null || git -C "$FORMAL_ROOT" fetch -q origin pull/71/head +git -C "$FORMAL_ROOT" checkout -q --detach "$FORMAL_REF" +echo "formal_head: $(git -C "$FORMAL_ROOT" rev-parse HEAD)" | tee -a "$LOGS/00-environment.log" + +# Keep all flags in one --flag argument. +COMMON_FLAGS="--cpp --realloc-lhs-arrays --separate-compilation" +CPU_FLAGS="$COMMON_FLAGS --gpu=cuda_cpu --device-compiler=$CUDA_CPU_CXX" +NATIVE_FLAGS="$COMMON_FLAGS --gpu=cuda --gpu-arch=$GPU_ARCH --device-compiler=$NVCC" +CPU_BUILD="$FORMAL_ROOT/build/cuda-cpu" +NATIVE_BUILD="$FORMAL_ROOT/build/cuda-nvidia" +HOST_BUILD="$FORMAL_ROOT/build/llvm-cpu-reference" +GF_BUILD="$FORMAL_ROOT/build/gfortran16-reference" +EXAMPLE="--example 2D-advection-diffusion" +GAUSS_ARGS="--solver workspace --order 4 --cells 17,13 --steps 9 --dt 1e-4 --no-csv" +OPS_ARGS="--solver operators --order 4 --cells 9,11 --steps 2 --dt 1e-4 --no-csv" + +# 2. CUDA CPU emulation. +step "formal tests, cuda_cpu" "$LOGS/10-fpm-test-cuda-cpu.log" \ + formal_fpm test --compiler "$LFORTRAN_COMPILER" --build-dir "$CPU_BUILD" --flag "$CPU_FLAGS" +step "operators solver, cuda_cpu" "$LOGS/11-operators-cuda-cpu.log" \ + formal_fpm run --compiler "$LFORTRAN_COMPILER" --build-dir "$CPU_BUILD" --flag "$CPU_FLAGS" $EXAMPLE -- $OPS_ARGS +step "workspace solver, cuda_cpu (dumps shared input)" "$LOGS/12-workspace-cuda-cpu.log" \ + formal_fpm run --compiler "$LFORTRAN_COMPILER" --build-dir "$CPU_BUILD" --flag "$CPU_FLAGS" $EXAMPLE -- $GAUSS_ARGS \ + --dump-input "$V/gaussian-input.fadv2d" --dump-final-raw "$V/gaussian-cuda-cpu-final.fadv2d" + +# Every `do concurrent` is offloaded. Without --gpu-allow-cpu-fallback a loop +# LFortran cannot offload is a compile error; with it, such a loop is +# reported as "parallel loop runs on the CPU" instead. Building all of +# Formal (library, tests, every example) with the fallback allowed and +# finding no such report shows that none would run on the host. +all_do_concurrent_offloaded() { + local b="$FORMAL_ROOT/build/fallback-check" log="$LOGS/19-fallback-build.log" + local f="$NATIVE_FLAGS --gpu-allow-cpu-fallback" + formal_fpm build --compiler "$LFORTRAN_COMPILER" --build-dir "$b" --flag "$f" --tests > "$log" 2>&1 || return 1 + for ex in $(cd "$FORMAL_ROOT/example" && ls *.F90 *.f90 2>/dev/null | sed 's/\.[Ff]90$//'); do + grep -qE "^\s*program\b" "$FORMAL_ROOT/example/$ex".[Ff]90 2>/dev/null || continue + formal_fpm run --compiler "$LFORTRAN_COMPILER" --build-dir "$b" --flag "$f" \ + --example "$ex" --runner true >> "$log" 2>&1 || return 1 + done + echo "do concurrent constructs in Formal: $(grep -rciE '^\s*([a-z_0-9]+\s*:\s*)?do\s+concurrent' \ + "$FORMAL_ROOT/src" "$FORMAL_ROOT/test" "$FORMAL_ROOT/example" | awk -F: '{s+=$2} END {print s}')" + echo "loops reported as running on the CPU: $(grep -c 'runs on the CPU' "$log")" + ! grep -q 'runs on the CPU' "$log" +} +step "every do concurrent offloaded (no CPU fallback)" "$LOGS/19-all-do-concurrent-offloaded.log" \ + all_do_concurrent_offloaded + +# 3. Native CUDA. With PTX JIT disabled a binary built for the wrong +# architecture fails instead of silently JIT compiling. +export CUDA_DISABLE_PTX_JIT=1 +step "formal tests, native cuda" "$LOGS/20-fpm-test-cuda-native.log" \ + formal_fpm test --compiler "$LFORTRAN_COMPILER" --build-dir "$NATIVE_BUILD" --flag "$NATIVE_FLAGS" +step "operators solver, native cuda" "$LOGS/21-operators-cuda-native.log" \ + formal_fpm run --compiler "$LFORTRAN_COMPILER" --build-dir "$NATIVE_BUILD" --flag "$NATIVE_FLAGS" $EXAMPLE -- $OPS_ARGS +# --input supplies cells, steps and dt; Formal rejects them together. +step "workspace solver, native cuda (shared input)" "$LOGS/22-workspace-cuda-native.log" \ + formal_fpm run --compiler "$LFORTRAN_COMPILER" --build-dir "$NATIVE_BUILD" --flag "$NATIVE_FLAGS" $EXAMPLE -- \ + --solver workspace --order 4 --no-csv --input "$V/gaussian-input.fadv2d" \ + --dump-final-raw "$V/gaussian-cuda-native-final.fadv2d" + +# 4. Executables: native GPU, host LLVM, independent GFortran 16 oracle. +step "capture native executable" "$LOGS/30-capture-native.log" \ + formal_fpm run --compiler "$LFORTRAN_COMPILER" --build-dir "$NATIVE_BUILD" --flag "$NATIVE_FLAGS" $EXAMPLE --runner cp -- "$V/formal-native" +step "capture host LLVM executable" "$LOGS/31-capture-host.log" \ + formal_fpm run --compiler "$LFORTRAN_COMPILER" --build-dir "$HOST_BUILD" --flag "$COMMON_FLAGS" $EXAMPLE --runner cp -- "$V/formal-host-llvm" +step "capture GFortran 16 executable" "$LOGS/32-capture-gfortran.log" \ + pixi run --manifest-path "$GF16_MANIFEST" /bin/bash -c 'cd "$FORMAL_ROOT" && exec fpm "$@"' _ \ + run --compiler gfortran --build-dir "$GF_BUILD" --flag "-cpp -O2 -ffree-line-length-none -fcoarray=single" \ + $EXAMPLE --runner cp -- "$V/formal-gfortran" +GF_LIB="$(pixi run --manifest-path "$GF16_MANIFEST" bash -c 'echo $CONDA_PREFIX/lib' 2>/dev/null)" + +# 5. Full-field comparisons. +step "gaussian 17x13/9: host LLVM reference" "$LOGS/40-gaussian-host.log" \ + "$V/formal-host-llvm" --solver workspace --order 4 --no-csv --input "$V/gaussian-input.fadv2d" \ + --dump-final-raw "$V/gaussian-host-final.fadv2d" +step "gaussian 17x13/9: native vs host (validate_2d_advection_workspace.py)" "$LOGS/41-gaussian-validate.log" \ + lf python "$FORMAL_ROOT/example/scripts/validate_2d_advection_workspace.py" \ + --executable "$V/formal-native" --workdir "$V/compare-native" \ + --raw-input "$V/gaussian-input.fadv2d" --reference-raw "$V/gaussian-host-final.fadv2d" \ + --cells 17,13 --steps 9 --dt 1e-4 --evolution --gpu-runner env + +lf python "$HERE/make_boundary_input.py" "$V/boundary-input.fadv2d" 13 11 3 1e-4 > "$LOGS/50-boundary-input.log" 2>&1 +for exe in native host-llvm gfortran; do + step "boundary 13x11/3: $exe" "$LOGS/51-boundary-$exe.log" \ + env LD_LIBRARY_PATH="$GF_LIB${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" "$V/formal-$exe" \ + --solver workspace --order 4 --no-csv --input "$V/boundary-input.fadv2d" \ + --dump-final-raw "$V/boundary-$exe-final.fadv2d" + # The comparator takes the oracle payloads without the FADV2D1 header. + python3 -c 'import sys; b=open(sys.argv[1],"rb").read().split(b"\n",3); assert b[2]==b"mode raw-final"; open(sys.argv[2],"wb").write(b[3])' \ + "$V/boundary-$exe-final.fadv2d" "$V/boundary-$exe-final.bin" 2>/dev/null +done +step "boundary 13x11/3: native vs GFortran vs host (compare_2d_raw_fields.py)" "$LOGS/52-boundary-compare.log" \ + lf python "$FORMAL_ROOT/example/scripts/compare_2d_raw_fields.py" \ + "$V/boundary-input.fadv2d" "$V/boundary-native-final.fadv2d" "$V/boundary-gfortran-final.bin" \ + --cells 13,11 --steps 3 --evolution --cpu-final "$V/boundary-host-llvm-final.bin" + +# 6. Evidence of native execution. +step "embedded GPU code (cuobjdump)" "$LOGS/60-cuobjdump.log" \ + "$CUDA_BIN/cuobjdump" --list-elf --list-ptx "$V/formal-native" +if [ "${SKIP_PROFILE:-0}" != 1 ]; then + if [ -x "$CUDA_BIN/nsys" ]; then + step "nsys: workspace kernel launches" "$LOGS/61-nsys-workspace.log" bash -c " + cd '$V' && '$CUDA_BIN/nsys' profile -o nsys-workspace --force-overwrite true \ + ./formal-native --solver workspace --order 4 --no-csv --input gaussian-input.fadv2d && + '$CUDA_BIN/nsys' stats --report cuda_gpu_kern_sum,cuda_gpu_mem_time_sum,cuda_api_sum nsys-workspace.nsys-rep" + step "nsys: operators kernel launches" "$LOGS/62-nsys-operators.log" bash -c " + cd '$V' && '$CUDA_BIN/nsys' profile -o nsys-operators --force-overwrite true \ + ./formal-native $OPS_ARGS && + '$CUDA_BIN/nsys' stats --report cuda_gpu_kern_sum,cuda_gpu_mem_time_sum,cuda_api_sum nsys-operators.nsys-rep" + fi + if [ -x "$CUDA_BIN/compute-sanitizer" ]; then + for tool in memcheck racecheck synccheck initcheck; do + step "compute-sanitizer $tool: workspace" "$LOGS/63-sanitizer-$tool-workspace.log" \ + "$CUDA_BIN/compute-sanitizer" --tool $tool --error-exitcode 99 "$V/formal-native" \ + --solver workspace --order 4 --no-csv --input "$V/gaussian-input.fadv2d" + step "compute-sanitizer $tool: operators" "$LOGS/63-sanitizer-$tool-operators.log" \ + "$CUDA_BIN/compute-sanitizer" --tool $tool --error-exitcode 99 "$V/formal-native" $OPS_ARGS + done + fi +fi + +# 7. LFortran's GPU integration tests on the real GPU. +if [ "${SKIP_LFORTRAN_TESTS:-0}" != 1 ]; then + step "lfortran integration_tests -b cuda" "$LOGS/70-lfortran-cuda-tests.log" \ + bash -c "cd '$LFORTRAN_ROOT' && pixi run -e llvm11 integration_tests -b cuda -j$JOBS" +fi +unset CUDA_DISABLE_PTX_JIT + +echo +echo "Summary ($WORK):" +for line in "${SUMMARY[@]}"; do echo " $line"; done +grep -h 'tests passed' "$LOGS"/10-*.log "$LOGS"/20-*.log "$LOGS"/70-*.log 2>/dev/null | sed 's/^/ /' +grep -h 'sm_' "$LOGS/60-cuobjdump.log" | sed -E 's/.*\.(sm_[0-9a-z]+)\.(cubin|ptx)/\1 \2/' | sort | uniq -c | sed 's/^/ /' +exit $FAILED diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 5cf6e1bc431..0ee7ddc54e0 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -59,7 +59,7 @@ elseif (NOT LFORTRAN_BACKEND AND APPLE) endif() endif() -macro(RUN_UTIL RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_EXTRA_ARGS RUN_COPY_TO_BIN RUN_GFORTRAN_ARGS RUN_SHARED_LIBRARY_FILES) +macro(RUN_UTIL RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_EXTRA_ARGS RUN_COPY_TO_BIN RUN_GFORTRAN_ARGS RUN_SHARED_LIBRARY_FILES RUN_STATIC_LIBRARY_FILES) set(fail ${${RUN_FAIL}}) set(name ${${RUN_NAME}}) set(file_name ${${RUN_FILE_NAME}}) @@ -69,6 +69,7 @@ macro(RUN_UTIL RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_EXT set(copy_to_bin ${${RUN_COPY_TO_BIN}}) set(gfortran_args ${${RUN_GFORTRAN_ARGS}}) set(shared_library_files ${${RUN_SHARED_LIBRARY_FILES}}) + set(static_library_files ${${RUN_STATIC_LIBRARY_FILES}}) if (NOT name) message(FATAL_ERROR "Must specify the NAME argument") @@ -211,6 +212,11 @@ macro(RUN_UTIL RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_EXT target_compile_options(${name}_lib PRIVATE $<$:${extra_args}>) target_link_libraries(${name} PRIVATE ${name}_lib) endif() + if (static_library_files) + add_library(${name}_staticlib STATIC ${static_library_files}) + target_compile_options(${name}_staticlib PRIVATE $<$:${extra_args}>) + target_link_libraries(${name} PRIVATE ${name}_staticlib) + endif() add_test(${name} ${CURRENT_BINARY_DIR}/${name}) elseif (LFORTRAN_BACKEND STREQUAL "llvm_omp") add_executable(${name} ${file_name}.f90 ${extra_files}) @@ -259,6 +265,11 @@ macro(RUN_UTIL RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_EXT add_executable(${name} ${file_name}.f90 ${extra_files}) target_compile_options(${name} PUBLIC $<$:--gpu=cuda_cpu ${extra_args}>) target_link_options(${name} PUBLIC --gpu=cuda_cpu) + if (static_library_files) + add_library(${name}_staticlib STATIC ${static_library_files}) + target_compile_options(${name}_staticlib PRIVATE $<$:--gpu=cuda_cpu ${extra_args}>) + target_link_libraries(${name} PRIVATE ${name}_staticlib) + endif() add_test(${name} ${CURRENT_BINARY_DIR}/${name}) elseif (LFORTRAN_BACKEND STREQUAL "flang") add_executable(${name} ${file_name}.f90 ${extra_files}) @@ -278,6 +289,11 @@ macro(RUN_UTIL RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_EXT target_compile_options(${name}_lib PRIVATE $<$:${gfortran_args}>) target_link_libraries(${name} PRIVATE ${name}_lib) endif() + if (static_library_files) + add_library(${name}_staticlib STATIC ${static_library_files}) + target_compile_options(${name}_staticlib PRIVATE $<$:${gfortran_args}>) + target_link_libraries(${name} PRIVATE ${name}_staticlib) + endif() add_test(${name} ${CURRENT_BINARY_DIR}/${name}) endif() @@ -298,7 +314,7 @@ endmacro(RUN_UTIL) macro(RUN) set(options FAIL NO_FAST NO_FAST_MATH NO_DETECT_LEAKS NO_STD_F23 NO_LLVM_GOC) set(oneValueArgs NAME FILE INCLUDE_PATH COPY_TO_BIN NUM_IMAGES) - set(multiValueArgs LABELS EXTRAFILES EXTRA_ARGS GFORTRAN_ARGS SHARED_LIBRARY_FILES) + set(multiValueArgs LABELS EXTRAFILES EXTRA_ARGS GFORTRAN_ARGS SHARED_LIBRARY_FILES STATIC_LIBRARY_FILES) cmake_parse_arguments(RUN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) set(RUN_SMOKE_NAME "${RUN_NAME}") @@ -345,9 +361,9 @@ macro(RUN) endif() set(RUN_NAME "${RUN_NAME}_FAST") list(REMOVE_ITEM RUN_LABELS gfortran) # remove gfortran from --fast test - RUN_UTIL(RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_EXTRA_ARGS RUN_COPY_TO_BIN RUN_GFORTRAN_ARGS RUN_SHARED_LIBRARY_FILES) + RUN_UTIL(RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_EXTRA_ARGS RUN_COPY_TO_BIN RUN_GFORTRAN_ARGS RUN_SHARED_LIBRARY_FILES RUN_STATIC_LIBRARY_FILES) else () - RUN_UTIL(RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_EXTRA_ARGS RUN_COPY_TO_BIN RUN_GFORTRAN_ARGS RUN_SHARED_LIBRARY_FILES) + RUN_UTIL(RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_EXTRA_ARGS RUN_COPY_TO_BIN RUN_GFORTRAN_ARGS RUN_SHARED_LIBRARY_FILES RUN_STATIC_LIBRARY_FILES) endif() endmacro(RUN) @@ -2644,6 +2660,7 @@ RUN(NAME operator_overloading_42 LABELS gfortran llvm) RUN(NAME operator_overloading_43 LABELS gfortran llvm) RUN(NAME operator_overloading_44 LABELS gfortran llvm) RUN(NAME operator_overloading_45 LABELS gfortran llvm) +RUN(NAME operator_overloading_46 LABELS gfortran llvm) RUN(NAME custom_unary_operator_01 LABELS gfortran llvm llvm_wasm llvm_wasm_emcc) RUN(NAME custom_unary_operator_02 LABELS gfortran llvm llvm_wasm llvm_wasm_emcc) @@ -3194,7 +3211,7 @@ RUN(NAME realloc_lhs_30 LABELS gfortran llvm RUN(NAME automatic_allocation_01 LABELS gfortran llvm llvm_wasm llvm_wasm_emcc EXTRA_ARGS --std=f23) RUN(NAME automatic_allocation_02 LABELS gfortran llvm llvm_wasm llvm_wasm_emcc EXTRA_ARGS --std=f23) RUN(NAME automatic_allocation_03 LABELS gfortran llvm llvm_wasm llvm_wasm_emcc EXTRA_ARGS --std=f23) -RUN(NAME automatic_array_01 LABELS gfortran llvm cuda_cpu) +RUN(NAME automatic_array_01 LABELS gfortran llvm cuda cuda_cpu) RUN(NAME automatic_array_02 LABELS gfortran llvm) RUN(NAME automatic_array_03 LABELS gfortran llvm) @@ -5398,16 +5415,16 @@ RUN(NAME openmp_66 LABELS llvm_omp gfortran GFORTRAN_ARGS -fopenmp) RUN(NAME openmp_67 LABELS llvm_omp gfortran GFORTRAN_ARGS -fopenmp) RUN(NAME openmp_68 LABELS llvm_omp gfortran GFORTRAN_ARGS -fopenmp) RUN(NAME openmp_69 LABELS llvm_omp gfortran GFORTRAN_ARGS -fopenmp) -RUN(NAME openmp_70 LABELS metal cuda_cpu EXTRA_ARGS --openmp) -RUN(NAME openmp_71 LABELS metal cuda_cpu EXTRA_ARGS --openmp) -RUN(NAME openmp_72 LABELS metal cuda_cpu EXTRA_ARGS --openmp) +RUN(NAME openmp_70 LABELS metal cuda cuda_cpu EXTRA_ARGS --openmp) +RUN(NAME openmp_71 LABELS metal cuda cuda_cpu EXTRA_ARGS --openmp) +RUN(NAME openmp_72 LABELS metal cuda cuda_cpu EXTRA_ARGS --openmp) RUN(NAME openmp_73 LABELS llvm_omp gfortran GFORTRAN_ARGS -fopenmp) RUN(NAME openmp_74 LABELS gfortran llvm) -RUN(NAME openmp_75 LABELS gfortran metal cuda_cpu EXTRA_ARGS --openmp) -RUN(NAME openmp_76 LABELS gfortran metal cuda_cpu EXTRA_ARGS --openmp --gpu-offload-omp-loops GFORTRAN_ARGS -fopenmp) +RUN(NAME openmp_75 LABELS gfortran metal cuda cuda_cpu EXTRA_ARGS --openmp) +RUN(NAME openmp_76 LABELS gfortran metal cuda cuda_cpu EXTRA_ARGS --openmp --gpu-offload-omp-loops GFORTRAN_ARGS -fopenmp) RUN(NAME openmp_77 LABELS llvm llvm_omp) RUN(NAME openmp_78 LABELS gfortran llvm llvm_omp GFORTRAN_ARGS -fopenmp) -RUN(NAME openmp_79 LABELS gfortran metal cuda_cpu llvm_omp EXTRA_ARGS --openmp) +RUN(NAME openmp_79 LABELS gfortran metal cuda cuda_cpu llvm_omp EXTRA_ARGS --openmp) RUN(NAME openmp_80 LABELS gfortran llvm_omp GFORTRAN_ARGS -fopenmp) RUN(NAME openmp_82 LABELS gfortran llvm_omp GFORTRAN_ARGS -fopenmp) RUN(NAME openmp_83 LABELS gfortran llvm_omp GFORTRAN_ARGS -fopenmp) @@ -5914,215 +5931,217 @@ RUN(NAME coarrays_53 EXTRA_ARGS --coarray=true EXTRAFILES coarrays_53_sub.f90) # is registered below without the gpu labels until the gap is closed, and the # diagnostic is tracked by a `gpu_offload_cuda` or `gpu_offload_metal` # reference test in tests/tests.toml. -RUN(NAME gpu_metal_01 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_02 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_03 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_04 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_metal_01 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_02 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_03 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_04 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) RUN(NAME gpu_metal_05 LABELS gfortran llvm metal cuda cuda_cpu) RUN(NAME gpu_metal_06 LABELS gfortran llvm metal cuda cuda_cpu) RUN(NAME gpu_metal_07 LABELS gfortran llvm metal cuda cuda_cpu) RUN(NAME gpu_metal_08 LABELS gfortran llvm metal cuda cuda_cpu) -RUN(NAME gpu_metal_09 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_10 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_11 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_12 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_13 LABELS gfortran llvm cuda_cpu) -RUN(NAME gpu_metal_14 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_15 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_16 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_17 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_18 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_19 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_20 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_21 LABELS llvm metal cuda_cpu) -RUN(NAME gpu_metal_22 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_23 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_24 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_25 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_26 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_27 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_28 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_29 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_30 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_31 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_32 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_33 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_34 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_35 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_36 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_37 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_38 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_39 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_40 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_41 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_42 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_43 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_44 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_45 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_46 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_47 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_48 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_49 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_50 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_51 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_52 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_53 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_54 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_55 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_56 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_57 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_58 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_59 LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_metal_09 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_10 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_11 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_12 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_13 LABELS gfortran llvm cuda cuda_cpu) +RUN(NAME gpu_metal_14 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_15 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_16 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_17 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_18 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_19 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_20 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_21 LABELS llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_22 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_23 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_24 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_25 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_26 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_27 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_28 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_29 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_30 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_31 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_32 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_33 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_34 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_35 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_36 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_37 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_38 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_39 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_40 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_41 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_42 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_43 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_44 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_45 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_46 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_47 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_48 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_49 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_50 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_51 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_52 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_53 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_54 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_55 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_56 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_57 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_58 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_59 LABELS gfortran llvm metal cuda cuda_cpu) RUN(NAME gpu_metal_60 LABELS gfortran llvm) -RUN(NAME gpu_metal_61 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_62 LABELS llvm metal cuda_cpu) -RUN(NAME gpu_metal_63 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_64 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_65 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_66 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_67 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_68 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_69 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_70 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_71 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_72 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_73 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_74 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_75 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_76 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_77 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_78 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_79 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_80 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_81 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_82 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_83 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_84 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_85 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_86 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_87 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_88 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_89 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_90 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_91 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_92 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_93 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_94 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_95 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_96 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_97 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_98 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_99 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_100 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_101 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_102 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_103 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_104 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_105 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_106 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_107 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_108 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_109 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_110 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_111 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_112 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_113 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_114 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_115 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_116 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_117 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_118 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_119 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_120 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_121 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_122 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_123 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_124 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_125 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_126 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_127 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_128 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_129 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_130 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_131 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_132 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_133 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_134 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_134_mod.f90 EXTRA_ARGS --separate-compilation) -RUN(NAME gpu_metal_135 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_135_mod.f90 EXTRA_ARGS --separate-compilation) -RUN(NAME gpu_metal_136 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_136_mod.f90 EXTRA_ARGS --separate-compilation) -RUN(NAME gpu_metal_137 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_138 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_139 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_140 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_140_mod.f90 EXTRA_ARGS --separate-compilation) -RUN(NAME gpu_metal_141 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_142 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_142_mod.f90 EXTRA_ARGS --separate-compilation) -RUN(NAME gpu_metal_143 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_144 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_144_mod.f90 EXTRA_ARGS --separate-compilation) -RUN(NAME gpu_metal_145 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_146 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_147 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_147_activation.f90 gpu_metal_147_neural_network.f90 EXTRA_ARGS --separate-compilation) -RUN(NAME gpu_metal_148 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_149 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_150 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_151 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_151_dep.f90 gpu_metal_151_net.f90 EXTRA_ARGS --separate-compilation) -RUN(NAME gpu_metal_152 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_153 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_154 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_155 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_156 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_157 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_158 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_159 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_160 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_161 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_161_mod.f90 EXTRA_ARGS --separate-compilation) +RUN(NAME gpu_metal_61 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_62 LABELS llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_63 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_64 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_65 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_66 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_67 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_68 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_69 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_70 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_71 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_72 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_73 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_74 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_75 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_76 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_77 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_78 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_79 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_80 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_81 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_82 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_83 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_84 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_85 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_86 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_87 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_88 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_89 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_90 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_91 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_92 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_93 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_94 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_95 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_96 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_97 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_98 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_99 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_100 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_101 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_102 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_103 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_104 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_105 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_106 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_107 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_108 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_109 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_110 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_111 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_112 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_113 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_114 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_115 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_116 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_117 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_118 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_119 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_120 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_121 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_122 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_123 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_124 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_125 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_126 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_127 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_128 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_129 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_130 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_131 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_132 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_133 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_134 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_134_mod.f90 EXTRA_ARGS --separate-compilation) +RUN(NAME gpu_metal_135 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_135_mod.f90 EXTRA_ARGS --separate-compilation) +RUN(NAME gpu_metal_136 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_136_mod.f90 EXTRA_ARGS --separate-compilation) +RUN(NAME gpu_metal_137 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_138 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_139 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_140 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_140_mod.f90 EXTRA_ARGS --separate-compilation) +RUN(NAME gpu_metal_141 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_142 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_142_mod.f90 EXTRA_ARGS --separate-compilation) +RUN(NAME gpu_metal_143 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_144 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_144_mod.f90 EXTRA_ARGS --separate-compilation) +RUN(NAME gpu_metal_145 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_146 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_147 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_147_activation.f90 gpu_metal_147_neural_network.f90 EXTRA_ARGS --separate-compilation) +RUN(NAME gpu_metal_148 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_149 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_150 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_cuda_cpu_01 LABELS gfortran llvm cuda_cpu EXTRAFILES gpu_cuda_cpu_01_mod.f90 EXTRA_ARGS --separate-compilation) +RUN(NAME gpu_cuda_cpu_archive_01 LABELS gfortran llvm cuda_cpu STATIC_LIBRARY_FILES gpu_cuda_cpu_archive_01_mod.f90 EXTRA_ARGS --separate-compilation) +RUN(NAME gpu_metal_151 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_151_dep.f90 gpu_metal_151_net.f90 EXTRA_ARGS --separate-compilation) +RUN(NAME gpu_metal_152 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_153 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_154 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_155 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_156 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_157 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_158 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_159 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_160 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_161 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_161_mod.f90 EXTRA_ARGS --separate-compilation) RUN(NAME gpu_metal_162 LABELS gfortran llvm) -RUN(NAME gpu_metal_163 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_164 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_165 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_166 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_167 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_168 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_169 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_170 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_171 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_172 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_173 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_174 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_175 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_176 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_177 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_178 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_179 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_180 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_181 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_182 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_183 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_184 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_185 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_186 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_187 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_188 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_189 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_190 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_191 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_192 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_193 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_194 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_195 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_196 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_197 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_198 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_199 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_200 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_201 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_202 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_203 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_204 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --gpu-allow-cpu-fallback) -RUN(NAME gpu_metal_205 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_206 LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_metal_163 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_164 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_165 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_166 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_167 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_168 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_169 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_170 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_171 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_172 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_173 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_174 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_175 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_176 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_177 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_178 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_179 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_180 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_181 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_182 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_183 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_184 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_185 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_186 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_187 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_188 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_189 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_190 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_191 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_192 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_193 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_194 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_195 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_196 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_197 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_198 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_199 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_200 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_201 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_202 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_203 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_204 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --gpu-allow-cpu-fallback) +RUN(NAME gpu_metal_205 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_206 LABELS gfortran llvm metal cuda cuda_cpu) RUN(NAME gpu_metal_207 LABELS gfortran llvm) -RUN(NAME gpu_metal_208 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_209 LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_metal_208 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_209 LABELS gfortran llvm metal cuda cuda_cpu) # gpu_metal_210 onward were written against the Metal path. Twelve of # them are not labelled cuda_cpu: the CUDA lowering does not yet compile # them, and labelling a test for a backend that cannot run it says nothing @@ -6130,294 +6149,297 @@ RUN(NAME gpu_metal_209 LABELS gfortran llvm metal cuda_cpu) # CUDA path used to lower its logical(8) loop to a 4-byte int kernel rather # than decline it, so the label would have caught a wrong answer. It does # decline it now, and carries the label. -RUN(NAME gpu_metal_210 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_211 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_212 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_213 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) -RUN(NAME gpu_metal_214 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) -RUN(NAME gpu_metal_215 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) -RUN(NAME gpu_metal_216 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_metal_210 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_211 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_212 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_213 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_metal_214 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_metal_215 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_metal_216 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) RUN(NAME gpu_metal_217 LABELS gfortran llvm) -RUN(NAME gpu_metal_218 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) -RUN(NAME gpu_metal_219 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_metal_218 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_metal_219 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) RUN(NAME gpu_metal_220 LABELS gfortran llvm) -RUN(NAME gpu_metal_221 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_222 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_223 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_224 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_225 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_226 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_227 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_228 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_229 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_230 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_231 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_232 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_233 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_234 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_235 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_236 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_237 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_238 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_239 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_240 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_241 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_242 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_243 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_244 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_245 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_246 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_247 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_248 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_249 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_250 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_251 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_252 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_253 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_254 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_255 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_256 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_257 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_258 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_259 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_260 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_261 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_262 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_263 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_263_mod.f90 EXTRA_ARGS --separate-compilation --realloc-lhs-arrays) -RUN(NAME gpu_metal_264 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_265 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_266 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_267 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_268 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_269 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_270 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_221 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_222 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_223 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_224 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_225 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_226 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_227 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_228 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_229 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_230 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_231 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_232 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_233 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_234 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_235 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_236 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_237 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_238 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_239 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_240 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_241 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_242 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_243 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_244 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_245 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_246 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_247 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_248 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_249 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_250 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_251 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_252 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_253 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_254 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_255 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_256 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_257 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_258 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_259 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_260 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_261 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_262 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_263 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_263_mod.f90 EXTRA_ARGS --separate-compilation --realloc-lhs-arrays) +RUN(NAME gpu_metal_264 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_265 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_266 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_267 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_268 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_269 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_270 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) RUN(NAME gpu_metal_271 LABELS gfortran llvm) -RUN(NAME gpu_metal_272 LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_metal_272 LABELS gfortran llvm metal cuda cuda_cpu) RUN(NAME gpu_metal_273 LABELS gfortran llvm) -RUN(NAME gpu_metal_274 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_275 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_274 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_275 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) RUN(NAME gpu_metal_276 LABELS gfortran llvm) -RUN(NAME gpu_metal_277 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_278 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_279 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_280 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_281 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_281_mod.f90 EXTRA_ARGS --separate-compilation --realloc-lhs-arrays) -RUN(NAME gpu_metal_282 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_282_mod.f90 EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_283 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_283_mod.f90 EXTRA_ARGS --separate-compilation --realloc-lhs-arrays) -RUN(NAME gpu_metal_284 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_284_mod.f90 EXTRA_ARGS --separate-compilation --realloc-lhs-arrays) +RUN(NAME gpu_metal_277 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_278 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_279 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_280 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_281 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_281_mod.f90 EXTRA_ARGS --separate-compilation --realloc-lhs-arrays) +RUN(NAME gpu_metal_282 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_282_mod.f90 EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_283 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_283_mod.f90 EXTRA_ARGS --separate-compilation --realloc-lhs-arrays) +RUN(NAME gpu_metal_284 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_284_mod.f90 EXTRA_ARGS --separate-compilation --realloc-lhs-arrays) RUN(NAME gpu_metal_285 LABELS gfortran llvm EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_286 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_287 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_288 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_289 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_290 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_291 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --gpu-allow-cpu-fallback) -RUN(NAME gpu_metal_292 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_293 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_294 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_295 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_296 LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_metal_286 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_287 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_288 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_289 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_290 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_291 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --gpu-allow-cpu-fallback) +RUN(NAME gpu_metal_292 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_293 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_294 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_295 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_296 LABELS gfortran llvm metal cuda cuda_cpu) RUN(NAME gpu_metal_297 LABELS gfortran llvm) -RUN(NAME gpu_metal_298 LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_metal_298 LABELS gfortran llvm metal cuda cuda_cpu) RUN(NAME gpu_metal_299 LABELS gfortran llvm) -RUN(NAME gpu_metal_300 LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_metal_300 LABELS gfortran llvm metal cuda cuda_cpu) RUN(NAME gpu_metal_301 LABELS gfortran llvm) -RUN(NAME gpu_metal_302 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_303 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_304 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_305 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_306 LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_metal_302 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_303 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_304 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_305 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_306 LABELS gfortran llvm metal cuda cuda_cpu) # Fortran 2023 `(cond ? a : b)`; no gfortran, same reason as conditional_expr_*. -RUN(NAME gpu_metal_307 LABELS llvm metal cuda_cpu) -RUN(NAME gpu_metal_308 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_309 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_310 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_311 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_312 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_313 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_314 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_315 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_316 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_317 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_318 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_319 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_320 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_321 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_322 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_323 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_324 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_325 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_326 LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_metal_307 LABELS llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_308 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_309 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_310 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_311 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_312 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_313 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_314 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_315 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_316 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_317 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_318 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_319 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_320 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_321 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_322 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_323 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_324 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_325 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_326 LABELS gfortran llvm metal cuda cuda_cpu) RUN(NAME gpu_metal_327 LABELS gfortran llvm EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_328 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_329 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_330 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) -RUN(NAME gpu_metal_331 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_332 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_333 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_334 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_335 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_336 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_337 FAIL LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_338 LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_metal_328 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_329 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_330 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_metal_331 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_332 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_333 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_334 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_335 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_336 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_337 FAIL LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_338 LABELS gfortran llvm metal cuda cuda_cpu) # No gfortran label: `reduce` is F2023, and the gfortran the CI builds with # rejects it outright ("Syntax error in DO statement"). Same reason # gpu_metal_21 above carries none. Checked by hand against gfortran 16, # which does accept it. -RUN(NAME gpu_metal_339 LABELS llvm metal cuda_cpu) -RUN(NAME gpu_metal_340 LABELS llvm metal cuda_cpu EXTRA_ARGS --separate-compilation) # `shared` locality is not accepted by every supported gfortran -RUN(NAME gpu_metal_341 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_342 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_343 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_344 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_345 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) -RUN(NAME gpu_metal_346 LABELS gfortran llvm cuda_cpu) -RUN(NAME gpu_metal_347 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) -RUN(NAME gpu_metal_348 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_349 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_350 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_351 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_352 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_353 LABELS llvm metal cuda_cpu) # conditional expressions are not accepted by every supported gfortran -RUN(NAME gpu_metal_354 LABELS llvm metal cuda_cpu) # conditional expressions are not accepted by every supported gfortran -RUN(NAME gpu_metal_355 LABELS llvm metal cuda_cpu) # `local` locality is not accepted by every supported gfortran -RUN(NAME gpu_metal_356 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_372 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_357 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_360 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_361 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_362 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_365 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_366 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_371 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_367 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_373 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_374 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_378 LABELS llvm cuda_cpu) # integer(8) loop index is supported on cuda_cpu; metal declines integer(8); gfortran on CI lacks reduce clause -RUN(NAME gpu_metal_379 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_380 LABELS llvm metal cuda_cpu) # gfortran on CI lacks reduce clause -RUN(NAME gpu_metal_383 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_384 FAIL LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_metal_339 LABELS llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_340 LABELS llvm metal cuda cuda_cpu EXTRA_ARGS --separate-compilation) # `shared` locality is not accepted by every supported gfortran +RUN(NAME gpu_metal_341 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_342 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_343 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_344 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_345 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_metal_346 LABELS gfortran llvm cuda cuda_cpu) +RUN(NAME gpu_metal_347 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_metal_348 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_349 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_350 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_351 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_352 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_353 LABELS llvm metal cuda cuda_cpu) # conditional expressions are not accepted by every supported gfortran +RUN(NAME gpu_metal_354 LABELS llvm metal cuda cuda_cpu) # conditional expressions are not accepted by every supported gfortran +RUN(NAME gpu_metal_355 LABELS llvm metal cuda cuda_cpu) # `local` locality is not accepted by every supported gfortran +RUN(NAME gpu_metal_356 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_372 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_357 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_360 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_361 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_362 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_365 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_366 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_371 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_367 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_373 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_374 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_378 LABELS llvm cuda cuda_cpu) # integer(8) loop index is supported on cuda_cpu; metal declines integer(8); gfortran on CI lacks reduce clause +RUN(NAME gpu_metal_379 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_380 LABELS llvm metal cuda cuda_cpu) # gfortran on CI lacks reduce clause +RUN(NAME gpu_metal_383 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_384 FAIL LABELS gfortran llvm metal cuda cuda_cpu) # gpu_metal_381 has a BLOCK array whose extent is known only at run time, # which a Metal shader cannot declare yet, so it has no metal label. -RUN(NAME gpu_metal_381 LABELS gfortran llvm cuda_cpu) -RUN(NAME gpu_metal_382 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_386 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_387 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_388 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_389 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_390 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_391 LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_metal_381 LABELS gfortran llvm cuda cuda_cpu) +RUN(NAME gpu_metal_382 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_386 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_387 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_388 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_389 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_390 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_391 LABELS gfortran llvm metal cuda cuda_cpu) RUN(NAME gpu_metal_406 LABELS gfortran llvm) # the GPU backends report an error, see tests/tests.toml RUN(NAME gpu_metal_407 LABELS gfortran llvm) # the GPU backends report an error, see tests/tests.toml -RUN(NAME gpu_metal_408 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_392 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_393 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_394 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_409 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_410 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_411 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_412 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_408 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_392 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_393 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_394 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_409 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_410 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_411 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_412 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) # A component whose size the host cannot work out before the loop: the # value is made on the device heap and copied out after the launch. -RUN(NAME gpu_metal_358 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_368 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_376 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_358 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_368 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_376 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) # A launch that allocates more than the device heap holds stops; on the CPU # each iteration frees what it allocates, so the test is GPU-only. -RUN(NAME gpu_metal_414 FAIL LABELS metal cuda_cpu) -RUN(NAME gpu_metal_415 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_416 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays --no-array-bounds-checking) -RUN(NAME gpu_metal_419 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_420 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_417 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_418 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_421 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_422 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_423 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_424 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_425 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_426 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_427 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_428 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_429 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_430 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_431 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_432 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_433 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_434 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) -RUN(NAME gpu_metal_436 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_437 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_438 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_439 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_440 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_441 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_442 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_443 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_444 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_450 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_449 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_454 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_445 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_460 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_461 FAIL LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_462 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_463 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_464 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_465 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_447 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_448 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_455 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_456 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_451 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_452 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_453 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_470 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_471 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_472 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_473 FAIL LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_474 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_475 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_476 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_477 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_478 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_479 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_480 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_481 LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_metal_414 FAIL LABELS metal cuda cuda_cpu) +RUN(NAME gpu_metal_415 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_416 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays --no-array-bounds-checking) +RUN(NAME gpu_metal_419 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_420 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_417 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_418 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_421 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_422 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_423 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_424 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_425 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_426 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_427 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_428 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_429 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_430 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_431 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_432 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_433 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_434 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_metal_436 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_437 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_438 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_439 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_440 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_441 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_442 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_443 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_444 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_450 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_449 LABELS gfortran llvm metal cuda_cpu cuda) +RUN(NAME gpu_metal_454 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_445 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_460 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_461 FAIL LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_462 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_463 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_464 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_465 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_447 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_448 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_455 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_456 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_451 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_452 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_453 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_470 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_471 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_472 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_473 FAIL LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_474 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_475 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_476 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_477 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_478 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_479 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_480 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_481 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_484 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_483 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_482 LABELS gfortran llvm metal cuda_cpu cuda) # gfortran evaluates a `do concurrent` limit twice, so gpu_metal_369 has no # gfortran label. The llvm backend and gfortran evaluate the limits of an # inner index again for every value of the outer one, so gpu_metal_370 is for # the GPU backends only. -RUN(NAME gpu_metal_369 LABELS llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_370 LABELS metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_369 LABELS llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_370 LABELS metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) # Expected run-time errors on the GPU backends only. gpu_metal_359 and # gpu_metal_363 are GPU-only because the llvm backend still allocates array # components in `t(i) = f(...)` without --realloc-lhs-arrays (#9738). # gpu_metal_375 is GPU-only for the same reason as gpu_metal_363 (#9738). -RUN(NAME gpu_metal_375 FAIL NO_FAST LABELS metal cuda_cpu) # bounds checking reports a component written in both branches of an `if` that is not allocated without --realloc-lhs-arrays -RUN(NAME gpu_metal_359 FAIL NO_FAST LABELS metal cuda_cpu) # bounds checking reports a component that is not allocated without --realloc-lhs-arrays -RUN(NAME gpu_metal_363 FAIL NO_FAST LABELS metal cuda_cpu) # bounds checking reports a component an `if` lets the loop write that is not allocated without --realloc-lhs-arrays -RUN(NAME gpu_metal_364 FAIL NO_FAST NO_STD_F23 LABELS llvm metal cuda_cpu) # bounds checking reports a component the loop assigns an array to that is not allocated without --realloc-lhs-arrays; --std=f23 allocates it on assignment -RUN(NAME gpu_metal_377 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_377_mod.f90 EXTRA_ARGS --separate-compilation) -RUN(NAME gpu_metal_385 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_385_mod.f90 EXTRA_ARGS --separate-compilation) -RUN(NAME gpu_metal_395 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_395_mod.f90 EXTRA_ARGS --separate-compilation) -RUN(NAME gpu_metal_396 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --fast) -RUN(NAME gpu_metal_397 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_398 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_399 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_400 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_401 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_402 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_403 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) -RUN(NAME gpu_metal_404 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_405 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_metal_413 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_413_mod.f90 EXTRA_ARGS --separate-compilation --realloc-lhs-arrays) -RUN(NAME gpu_metal_435 LABELS gfortran llvm metal cuda_cpu EXTRAFILES gpu_metal_435_mod.f90 EXTRA_ARGS --separate-compilation $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_metal_375 FAIL NO_FAST LABELS metal cuda cuda_cpu) # bounds checking reports a component written in both branches of an `if` that is not allocated without --realloc-lhs-arrays +RUN(NAME gpu_metal_359 FAIL NO_FAST LABELS metal cuda cuda_cpu) # bounds checking reports a component that is not allocated without --realloc-lhs-arrays +RUN(NAME gpu_metal_363 FAIL NO_FAST LABELS metal cuda cuda_cpu) # bounds checking reports a component an `if` lets the loop write that is not allocated without --realloc-lhs-arrays +RUN(NAME gpu_metal_364 FAIL NO_FAST NO_STD_F23 LABELS llvm metal cuda cuda_cpu) # bounds checking reports a component the loop assigns an array to that is not allocated without --realloc-lhs-arrays; --std=f23 allocates it on assignment +RUN(NAME gpu_metal_377 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_377_mod.f90 EXTRA_ARGS --separate-compilation) +RUN(NAME gpu_metal_385 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_385_mod.f90 EXTRA_ARGS --separate-compilation) +RUN(NAME gpu_metal_395 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_395_mod.f90 EXTRA_ARGS --separate-compilation) +RUN(NAME gpu_metal_396 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --fast) +RUN(NAME gpu_metal_397 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_398 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_399 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_400 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_401 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_402 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_403 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --realloc-lhs-arrays) +RUN(NAME gpu_metal_404 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_405 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_metal_413 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_413_mod.f90 EXTRA_ARGS --separate-compilation --realloc-lhs-arrays) +RUN(NAME gpu_metal_435 LABELS gfortran llvm metal cuda cuda_cpu EXTRAFILES gpu_metal_435_mod.f90 EXTRA_ARGS --separate-compilation $<$:--gpu-allow-cpu-fallback>) RUN(NAME inline_scoped_01 LABELS gfortran llvm EXTRA_ARGS --fast) RUN(NAME inline_function_calls_01 LABELS gfortran llvm EXTRA_ARGS --fast) -RUN(NAME gpu_decline_01 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_decline_02 LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_decline_01 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_decline_02 LABELS gfortran llvm metal cuda cuda_cpu) RUN(NAME gpu_decline_03 LABELS gfortran llvm EXTRAFILES gpu_decline_03_ext.f90) RUN(NAME gpu_decline_04 LABELS gfortran llvm) RUN(NAME gpu_decline_05 LABELS gfortran llvm) @@ -6434,18 +6456,21 @@ RUN(NAME gpu_decline_13 LABELS gfortran) RUN(NAME gpu_decline_14 LABELS gfortran llvm) RUN(NAME gpu_decline_15 LABELS gfortran llvm) RUN(NAME gpu_decline_16 LABELS gfortran llvm) +RUN(NAME gpu_decline_17 LABELS gfortran llvm) +RUN(NAME gpu_decline_18 LABELS gfortran llvm) +RUN(NAME gpu_decline_19 LABELS gfortran llvm) # One program per entry of the GPU unsupported list. Each runs on the CPU with # --gpu-allow-cpu-fallback where its loop is on the list, and the error # without the flag is kept by a reference test in tests/tests.toml. -RUN(NAME gpu_unsupported_01 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) -RUN(NAME gpu_unsupported_02 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) -RUN(NAME gpu_unsupported_03 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) -RUN(NAME gpu_unsupported_04 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) -RUN(NAME gpu_unsupported_05 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_unsupported_06 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --gpu-allow-cpu-fallback) -RUN(NAME gpu_unsupported_07 LABELS gfortran llvm metal cuda_cpu EXTRA_ARGS --gpu-allow-cpu-fallback) -RUN(NAME gpu_unsupported_08 LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_unsupported_01 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_unsupported_02 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_unsupported_03 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_unsupported_04 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS $<$:--gpu-allow-cpu-fallback>) +RUN(NAME gpu_unsupported_05 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_unsupported_06 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --gpu-allow-cpu-fallback) +RUN(NAME gpu_unsupported_07 LABELS gfortran llvm metal cuda cuda_cpu EXTRA_ARGS --gpu-allow-cpu-fallback) +RUN(NAME gpu_unsupported_08 LABELS gfortran llvm metal cuda cuda_cpu) RUN(NAME gpu_kernel_source_01 LABELS gfortran llvm) RUN(NAME gpu_kernel_source_02 LABELS gfortran llvm) @@ -6456,10 +6481,13 @@ RUN(NAME gpu_kernel_source_06 LABELS gfortran llvm) RUN(NAME gpu_kernel_source_07 LABELS gfortran llvm) RUN(NAME gpu_kernel_source_08 LABELS gfortran llvm) RUN(NAME gpu_kernel_source_09 LABELS gfortran llvm) -RUN(NAME gpu_kernel_source_10 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_kernel_source_11 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_kernel_source_12 LABELS gfortran llvm metal cuda_cpu) -RUN(NAME gpu_kernel_source_13 LABELS gfortran llvm metal cuda_cpu) +RUN(NAME gpu_kernel_source_10 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_kernel_source_11 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_kernel_source_12 LABELS gfortran llvm metal cuda_cpu cuda) +RUN(NAME gpu_kernel_source_13 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_kernel_source_15 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_kernel_source_14 LABELS gfortran llvm metal cuda cuda_cpu) +RUN(NAME gpu_kernel_source_16 LABELS gfortran llvm metal cuda cuda_cpu) RUN(NAME real128_arith_01 LABELS gfortran llvm) RUN(NAME real128_arith_02 LABELS gfortran llvm) diff --git a/integration_tests/gpu_cuda_cpu_01.f90 b/integration_tests/gpu_cuda_cpu_01.f90 new file mode 100644 index 00000000000..e5fd89ee8d1 --- /dev/null +++ b/integration_tests/gpu_cuda_cpu_01.f90 @@ -0,0 +1,17 @@ +program gpu_cuda_cpu_01 + use gpu_cuda_cpu_01_m, only: transform_t, shift_up + implicit none + type(transform_t) :: t + real :: x(4), y(4) + integer :: i + x = [1.0, 2.0, 3.0, 4.0] + call shift_up(x) + do concurrent (i = 1:4) + y(i) = t%apply(x(i)) + end do + if (abs(y(1) - 4.0) > 1e-6) error stop 1 + if (abs(y(2) - 6.0) > 1e-6) error stop 2 + if (abs(y(3) - 8.0) > 1e-6) error stop 3 + if (abs(y(4) - 10.0) > 1e-6) error stop 4 + print *, "ok" +end program diff --git a/integration_tests/gpu_cuda_cpu_01_mod.f90 b/integration_tests/gpu_cuda_cpu_01_mod.f90 new file mode 100644 index 00000000000..d8919e49910 --- /dev/null +++ b/integration_tests/gpu_cuda_cpu_01_mod.f90 @@ -0,0 +1,30 @@ +module gpu_cuda_cpu_01_m + implicit none + type :: transform_t + contains + procedure :: apply => my_apply + end type + interface + elemental module function my_apply(self, x) result(y) + class(transform_t), intent(in) :: self + real, intent(in) :: x + real :: y + end function + end interface +contains + subroutine shift_up(x) + real, intent(inout) :: x(4) + integer :: i + do concurrent (i = 1:4) + x(i) = x(i) + 1.0 + end do + end subroutine +end module + +submodule (gpu_cuda_cpu_01_m) gpu_cuda_cpu_01_s + implicit none +contains + module procedure my_apply + y = x * 2.0 + end procedure +end submodule diff --git a/integration_tests/gpu_cuda_cpu_archive_01.f90 b/integration_tests/gpu_cuda_cpu_archive_01.f90 new file mode 100644 index 00000000000..4d928e92f8a --- /dev/null +++ b/integration_tests/gpu_cuda_cpu_archive_01.f90 @@ -0,0 +1,10 @@ +program gpu_cuda_cpu_archive_01 + use gpu_cuda_cpu_archive_01_m, only: twice + implicit none + real :: x(4), y(4) + x = [1.0, 2.0, 3.0, 4.0] + y = -1.0 + call twice(x, y) + if (any(y /= [2.0, 4.0, 6.0, 8.0])) error stop 1 + print *, "ok" +end program diff --git a/integration_tests/gpu_cuda_cpu_archive_01_mod.f90 b/integration_tests/gpu_cuda_cpu_archive_01_mod.f90 new file mode 100644 index 00000000000..37e5ca52eb7 --- /dev/null +++ b/integration_tests/gpu_cuda_cpu_archive_01_mod.f90 @@ -0,0 +1,12 @@ +module gpu_cuda_cpu_archive_01_m + implicit none +contains + subroutine twice(x, y) + real, intent(in) :: x(4) + real, intent(out) :: y(4) + integer :: i + do concurrent (i = 1:4) + y(i) = 2.0*x(i) + end do + end subroutine +end module diff --git a/integration_tests/gpu_decline_17.f90 b/integration_tests/gpu_decline_17.f90 new file mode 100644 index 00000000000..7c58208fa87 --- /dev/null +++ b/integration_tests/gpu_decline_17.f90 @@ -0,0 +1,27 @@ +! gpu decline reason: LocalityElementType +! An array of LOCAL locality is a new array in each iteration. Each thread +! needs a copy of its own, and an array of derived type is not one a thread +! can hold as a local yet: one buffer shared by every thread would be a +! race, so the loop is not offloaded. +program gpu_decline_17 +implicit none +type :: pair + real :: a +end type +integer, parameter :: n = 1000 +real :: x(n), g(n) +type(pair) :: t(2) +integer :: j +do j = 1, n + x(j) = real(j) +end do +do concurrent (j = 1:n) local(t) + t(1)%a = x(j) + t(2)%a = 2.0 * x(j) + g(j) = t(1)%a + t(2)%a +end do +do j = 1, n + if (abs(g(j) - 3.0 * x(j)) > 1.0e-3) error stop +end do +print *, "ok" +end program diff --git a/integration_tests/gpu_decline_18.f90 b/integration_tests/gpu_decline_18.f90 new file mode 100644 index 00000000000..42628e550f3 --- /dev/null +++ b/integration_tests/gpu_decline_18.f90 @@ -0,0 +1,26 @@ +! gpu decline reason: LocalityNamedByAssociate +! An array of LOCAL locality is a new array in each iteration, but an +! associate name of the construct around the loop still names the array +! outside it. The kernel resolves that name to the array itself, so it +! cannot tell the two apart, and the loop is not offloaded. +program gpu_decline_18 +implicit none +integer, parameter :: n = 1000 +real :: x(n), g(n), t(2) +integer :: j +do j = 1, n + x(j) = real(j) +end do +t = [10.0, 20.0] +associate (a => t) + do concurrent (j = 1:n) local(t) + t(1) = x(j) + t(2) = a(2) + g(j) = t(1) + t(2) + end do +end associate +do j = 1, n + if (abs(g(j) - (x(j) + 20.0)) > 1.0e-3) error stop +end do +print *, "ok" +end program diff --git a/integration_tests/gpu_decline_19.f90 b/integration_tests/gpu_decline_19.f90 new file mode 100644 index 00000000000..1522da3e781 --- /dev/null +++ b/integration_tests/gpu_decline_19.f90 @@ -0,0 +1,27 @@ +! gpu decline reason: LocalityAssociateNotInlined +! An array of LOCAL locality is a new array in each iteration, which the +! kernel makes a local of a BLOCK around the loop body. An ASSOCIATE inside +! an IF of the body is not one the kernel inlines into that BLOCK, so the +! array cannot be given a copy per thread, and the loop is not offloaded. +program gpu_decline_19 +implicit none +integer, parameter :: n = 1000 +real :: x(n), g(n), t(2) +integer :: j +do j = 1, n + x(j) = real(j) +end do +do concurrent (j = 1:n) local(t) + if (j > 0) then + associate (e => 2.0 * x(j)) + t(1) = x(j) + t(2) = e + g(j) = t(1) + t(2) + end associate + end if +end do +do j = 1, n + if (abs(g(j) - 3.0 * x(j)) > 1.0e-3) error stop +end do +print *, "ok" +end program diff --git a/integration_tests/gpu_kernel_source_14.f90 b/integration_tests/gpu_kernel_source_14.f90 new file mode 100644 index 00000000000..bced051822a --- /dev/null +++ b/integration_tests/gpu_kernel_source_14.f90 @@ -0,0 +1,44 @@ +program gpu_kernel_source_14 + ! Every iteration defines `t` whole before it references it, so `t` + ! is private to the iteration, and so is the temporary an array + ! constructor is lowered to. Each kernel must declare them as + ! locals of the thread, not take them as buffers every thread shares: + ! CI has no GPU that would expose the race, so the reference kernel + ! source is what checks this. The second loop names `u` in a LOCAL + ! locality specifier and defines it element by element. + implicit none + integer, parameter :: n = 8 + real :: x(n), g(4, n), t(4), u(4) + integer :: j + + do j = 1, n + x(j) = real(j) + end do + do concurrent (j = 1:n) + associate (e => 10.0 * x(j)) + t = [x(j), e, e + 1.0, e + 2.0] + g(:, j) = t + end associate + end do + do j = 1, n + if (abs(g(1, j) - x(j)) > 1.0e-5) error stop 1 + if (abs(g(2, j) - 10.0 * x(j)) > 1.0e-5) error stop 2 + if (abs(g(3, j) - (10.0 * x(j) + 1.0)) > 1.0e-5) error stop 3 + if (abs(g(4, j) - (10.0 * x(j) + 2.0)) > 1.0e-5) error stop 4 + end do + do concurrent (j = 1:n) local(u) + t = [x(j), 2.0 * x(j), 3.0 * x(j), 4.0 * x(j)] + u(1) = t(4) + u(2) = t(3) + u(3) = t(2) + u(4) = t(1) + g(:, j) = u + end do + do j = 1, n + if (abs(g(1, j) - 4.0 * x(j)) > 1.0e-5) error stop 5 + if (abs(g(2, j) - 3.0 * x(j)) > 1.0e-5) error stop 6 + if (abs(g(3, j) - 2.0 * x(j)) > 1.0e-5) error stop 7 + if (abs(g(4, j) - x(j)) > 1.0e-5) error stop 8 + end do + print *, "ok" +end program diff --git a/integration_tests/gpu_kernel_source_15.f90 b/integration_tests/gpu_kernel_source_15.f90 new file mode 100644 index 00000000000..eb5f19b78d2 --- /dev/null +++ b/integration_tests/gpu_kernel_source_15.f90 @@ -0,0 +1,36 @@ +program gpu_kernel_source_15 + ! A kernel, a block in it and a routine it calls declare only the + ! scalars and locals they refer to: the kernel does not use the + ! extent of `x` or `y` or the named constant `n`, but it does use the + ! leading extent of `z`; the block does not use `unused`, and the + ! function does not use `width` or `unused`. + implicit none + integer, parameter :: n = 8 + real, allocatable :: x(:), y(:), z(:,:) + real :: a + integer :: i + allocate(x(n), y(n), z(n, 2)) + a = 2.0 + x = 1.0 + y = 3.0 + z = 0.0 + do concurrent (i = 1:n) + block + real :: t, unused + t = a*x(i) + y(i) = t + y(i) + end block + z(i, 2) = twice(y(i)) + end do + if (any(abs(y - 5.0) > 1e-6)) error stop 1 + if (any(abs(z(:, 2) - 10.0) > 1e-6)) error stop 2 + if (any(z(:, 1) /= 0.0)) error stop 3 + print *, "ok" +contains + pure real function twice(v) + real, intent(in) :: v + integer, parameter :: width = 2 + real :: unused + twice = 2*v + end function +end program diff --git a/integration_tests/gpu_kernel_source_16.f90 b/integration_tests/gpu_kernel_source_16.f90 new file mode 100644 index 00000000000..f68b366dc32 --- /dev/null +++ b/integration_tests/gpu_kernel_source_16.f90 @@ -0,0 +1,53 @@ +module gpu_kernel_source_16_m +implicit none +contains + integer function bump(m) + integer, intent(inout) :: m + m = 2 + bump = 0 + end function +end module + +program gpu_kernel_source_16 + ! Arrays that must stay buffers every thread shares, which the + ! reference kernel source checks: making either a local of the thread + ! would change what the program computes. + use gpu_kernel_source_16_m + implicit none + integer, parameter :: n = 8 + real :: t(2), u(2), x(n), g(n) + integer :: j, k, y + + do j = 1, n + x(j) = real(j) + end do + + ! Each iteration defines `t` whole, but after the loop `t(1)` is read + ! before it is defined again: the call changes `k`, so `t(k) = 5.0` + ! defines `t(2)`, not `t(1)`, and `t(1)` keeps the value the loop + ! left there. + do concurrent (j = 1:1) + t = x(j) + 41.0 + g(j) = t(1) + end do + k = 1 + y = bump(k) + t(k) = 5.0 + t(2) = 5.0 + if (y /= 0 .or. k /= 2) error stop 1 + if (abs(t(1) - 42.0) > 1.0e-5) error stop 2 + + ! Each iteration defines only `u(1)`, the same element twice, and + ! then reads `u(2)`, which keeps the value it had before the loop. + u(2) = 9.0 + do concurrent (j = 1:n) + k = 1 + u(k) = 1.0 + u(k + 1 - 1) = 1.0 + g(j) = u(1) + u(2) + x(j) + end do + do j = 1, n + if (abs(g(j) - (10.0 + x(j))) > 1.0e-5) error stop 3 + end do + print *, "ok" +end program diff --git a/integration_tests/gpu_metal_482.f90 b/integration_tests/gpu_metal_482.f90 new file mode 100644 index 00000000000..5e554606265 --- /dev/null +++ b/integration_tests/gpu_metal_482.f90 @@ -0,0 +1,41 @@ +program gpu_metal_482 + ! A `do concurrent` loop with an empty index range launches no thread: + ! the arrays it would write keep their values, also when an earlier loop + ! left them on the device, and a reduction over it keeps its initial value. + implicit none + integer :: i, n, lo + integer :: a(5) + real :: x(100), s + n = 3 + lo = 7 + + a = -1 + do concurrent (i = lo:n) + a(i) = 0 + end do + if (any(a /= -1)) error stop 1 + + do concurrent (i = 1:5) + a(i) = i + end do + do concurrent (i = lo:n) + a(i) = 0 + end do + do i = 1, 5 + if (a(i) /= i) error stop 2 + end do + + x = 1 + s = 5 + do concurrent (i = lo:n) reduce(+:s) + s = s + x(i) + end do + if (abs(s - 5) > 1e-6) error stop 3 + + s = 0 + do concurrent (i = 1:100) reduce(+:s) + s = s + x(i) + end do + if (abs(s - 100) > 1e-6) error stop 4 + print *, a, s +end program diff --git a/integration_tests/gpu_metal_483.f90 b/integration_tests/gpu_metal_483.f90 new file mode 100644 index 00000000000..ba26b1879d8 --- /dev/null +++ b/integration_tests/gpu_metal_483.f90 @@ -0,0 +1,172 @@ +module gpu_metal_483_m +! A fixed-size local array that every iteration of a DO CONCURRENT loop +! defines whole before it references it is private to the iteration +! (Fortran 2018, 11.1.7.5). On a GPU it must become a per-thread local: +! one buffer that every thread writes and reads is a race, and with many +! threads in flight the last writer wins. The loops are long enough for +! a real GPU to run them in parallel. +implicit none +contains + + ! The definition sits inside an ASSOCIATE construct. + subroutine assoc_whole(x, g, n) + integer, intent(in) :: n + real, intent(in) :: x(n) + real, intent(out) :: g(4,n) + integer :: j + real :: t(4) + do concurrent (j = 1:n) + associate (e => 10.0 * x(j)) + t = [x(j), e, e + 1.0, e + 2.0] + g(:,j) = t + end associate + end do + end subroutine + + ! Nested ASSOCIATE constructs, the array defined by a DO loop. + subroutine assoc_nested(x, g, n) + integer, intent(in) :: n + real, intent(in) :: x(n) + real, intent(out) :: g(4,n) + integer :: j, k + real :: t(4) + do concurrent (j = 1:n) + associate (a => x(j)) + associate (b => 2.0 * a) + do k = 1, 4 + t(k) = b + real(k) + end do + g(:,j) = t(4:1:-1) + end associate + end associate + end do + end subroutine + + ! An explicit LOCAL locality specifier. + subroutine local_spec(x, g, n) + integer, intent(in) :: n + real, intent(in) :: x(n) + real, intent(out) :: g(4,n) + integer :: j + real :: t(4) + do concurrent (j = 1:n) local(t) + t = [x(j), 3.0 * x(j), 3.0 * x(j) + 1.0, 3.0 * x(j) + 2.0] + g(:,j) = t + end do + end subroutine + + ! A constructor outside any ASSOCIATE: its lowering fills a + ! temporary of the procedure element by element through a counter. + subroutine plain(x, g, n) + integer, intent(in) :: n + real, intent(in) :: x(n) + real, intent(out) :: g(4,n) + integer :: j + real :: t(4) + do concurrent (j = 1:n) + t = [x(j), 4.0 * x(j), 4.0 * x(j) + 1.0, 4.0 * x(j) + 2.0] + g(:,j) = t + end do + end subroutine + + ! Every element defined one by one, later ones reading earlier ones. + subroutine elements(x, g, n) + integer, intent(in) :: n + real, intent(in) :: x(n) + real, intent(out) :: g(4,n) + integer :: j + real :: t(2,2) + do concurrent (j = 1:n) + t(1,1) = x(j) + t(2,1) = 5.0 * x(j) + t(1,2) = t(2,1) + 1.0 + t(2,2) = t(1,2) + 1.0 + g(1:2,j) = t(:,1) + g(3:4,j) = t(:,2) + end do + end subroutine + + ! LOCAL locality of an array and of a scalar that are dummy + ! arguments. + subroutine local_dummies(x, g, n, t, s) + integer, intent(in) :: n + real, intent(in) :: x(n) + real, intent(out) :: g(4,n) + real, intent(inout) :: t(4), s + integer :: j + do concurrent (j = 1:n) local(t, s) + s = 6.0 * x(j) + t = [x(j), s, s + 1.0, s + 2.0] + g(:,j) = t + end do + end subroutine + +end module + +program gpu_metal_483 +use gpu_metal_483_m +implicit none +integer, parameter :: n = 100000 +real, allocatable :: x(:), g(:,:) +real :: tout(4), sout +integer :: j, k + +allocate(x(n), g(4,n)) +do j = 1, n + x(j) = real(mod(j, 997)) +end do + +g = 0.0 +call assoc_whole(x, g, n) +do j = 1, n + if (abs(g(1,j) - x(j)) > 1.0e-3) error stop "assoc_whole: element 1" + if (abs(g(2,j) - 10.0 * x(j)) > 1.0e-3) error stop "assoc_whole: element 2" + if (abs(g(3,j) - (10.0 * x(j) + 1.0)) > 1.0e-3) error stop "assoc_whole: element 3" + if (abs(g(4,j) - (10.0 * x(j) + 2.0)) > 1.0e-3) error stop "assoc_whole: element 4" +end do + +g = 0.0 +call assoc_nested(x, g, n) +do j = 1, n + do k = 1, 4 + if (abs(g(k,j) - (2.0 * x(j) + real(5 - k))) > 1.0e-3) error stop "assoc_nested" + end do +end do + +g = 0.0 +call local_spec(x, g, n) +do j = 1, n + if (abs(g(1,j) - x(j)) > 1.0e-3) error stop "local: element 1" + if (abs(g(2,j) - 3.0 * x(j)) > 1.0e-3) error stop "local: element 2" + if (abs(g(3,j) - (3.0 * x(j) + 1.0)) > 1.0e-3) error stop "local: element 3" + if (abs(g(4,j) - (3.0 * x(j) + 2.0)) > 1.0e-3) error stop "local: element 4" +end do + +g = 0.0 +call plain(x, g, n) +do j = 1, n + do k = 1, 4 + if (abs(g(k,j) - merge(x(j), 4.0 * x(j) + real(k - 2), k == 1)) > 1.0e-3) error stop "plain" + end do +end do + +g = 0.0 +call elements(x, g, n) +do j = 1, n + do k = 1, 4 + if (abs(g(k,j) - merge(x(j), 5.0 * x(j) + real(k - 2), k == 1)) > 1.0e-3) error stop "elements" + end do +end do + +g = 0.0 +tout = -1.0 +sout = -2.0 +call local_dummies(x, g, n, tout, sout) +do j = 1, n + do k = 1, 4 + if (abs(g(k,j) - merge(x(j), 6.0 * x(j) + real(k - 2), k == 1)) > 1.0e-3) error stop "local_dummies" + end do +end do + +print *, "ok" +end program diff --git a/integration_tests/gpu_metal_484.f90 b/integration_tests/gpu_metal_484.f90 new file mode 100644 index 00000000000..17f8deabd21 --- /dev/null +++ b/integration_tests/gpu_metal_484.f90 @@ -0,0 +1,82 @@ +module gpu_metal_484_m + implicit none +contains + pure function smooth(v) result(r) + real, intent(in) :: v(:) + real, allocatable :: r(:) + integer :: i + allocate(r(size(v))) + do i = 1, size(v) + r(i) = 0.5*v(i) + if (i > 1) r(i) = r(i) + 0.25*v(i-1) + if (i < size(v)) r(i) = r(i) + 0.25*v(i+1) + end do + end function + + pure function scaled(v, c) result(r) + real, intent(in) :: v(:), c + real, allocatable :: r(:) + allocate(r(size(v))) + r = c*v + 1.0 + end function + + ! Launches the same kernels, with per-thread workspaces sized by `m`, + ! `steps` times each, with no host access between the launches. + subroutine run(m, ncol, steps, a, b) + integer, intent(in) :: m, ncol, steps + real, intent(inout) :: a(m, ncol), b(m, ncol) + integer :: s, j + do s = 1, steps + do concurrent (j = 1:ncol) + b(:, j) = smooth(a(:, j)) + end do + do concurrent (j = 1:ncol) + a(:, j) = scaled(b(:, j), 0.5) + end do + end do + end subroutine + + subroutine run_ref(m, ncol, steps, a, b) + integer, intent(in) :: m, ncol, steps + real, intent(inout) :: a(m, ncol), b(m, ncol) + integer :: s, j + do s = 1, steps + do j = 1, ncol + b(:, j) = smooth(a(:, j)) + end do + do j = 1, ncol + a(:, j) = scaled(b(:, j), 0.5) + end do + end do + end subroutine +end module + +program gpu_metal_484 + use gpu_metal_484_m + implicit none + integer, parameter :: nsizes = 7 + integer, parameter :: sizes(nsizes) = [8, 40, 3, 72, 0, 16, 72] + integer, parameter :: ncols(nsizes) = [5, 33, 64, 9, 4, 1, 17] + real, allocatable :: a(:, :), b(:, :), ra(:, :), rb(:, :) + integer :: k, i, j, m, ncol + + do k = 1, nsizes + m = sizes(k) + ncol = ncols(k) + allocate(a(m, ncol), b(m, ncol), ra(m, ncol), rb(m, ncol)) + do j = 1, ncol + do i = 1, m + a(i, j) = real(mod(i + 3*j + k, 11)) + end do + end do + b = 0 + ra = a + rb = b + call run(m, ncol, 25, a, b) + call run_ref(m, ncol, 25, ra, rb) + if (any(abs(a - ra) > 1e-5)) error stop + if (any(abs(b - rb) > 1e-5)) error stop + deallocate(a, b, ra, rb) + end do + print *, "ok" +end program diff --git a/integration_tests/operator_overloading_46.f90 b/integration_tests/operator_overloading_46.f90 new file mode 100644 index 00000000000..a3e9ca6a861 --- /dev/null +++ b/integration_tests/operator_overloading_46.f90 @@ -0,0 +1,204 @@ +module operator_overloading_46_mod + implicit none + integer :: ncalls = 0 + + type :: div_t + real, allocatable :: v(:) + contains + generic :: operator(-) => dminus + generic :: operator(.neg.) => dneg + procedure :: dminus + procedure :: dneg + end type + + type :: vec_t + real, allocatable :: v(:) + contains + generic :: operator(.div.) => vdiv + procedure :: vdiv + end type + + type :: sc_t + real, allocatable :: v(:) + contains + generic :: assignment(=) => assign_div + procedure :: assign_div + end type + + type :: pt_t + real :: x = 0 + contains + generic :: operator(+) => padd + procedure :: padd + end type + + type :: base_t + integer :: k = 0 + contains + generic :: operator(*) => bmul + generic :: operator(+) => badd + procedure :: bmul + procedure :: badd + end type + + type, extends(base_t) :: child_t + contains + procedure :: bmul => cmul + procedure :: badd => cadd + end type + + interface operator(+) + module procedure dplus + end interface + +contains + + function mk(x) result(d) + real, intent(in) :: x + type(div_t) :: d + ncalls = ncalls + 1 + d%v = [x, x] + end function + + function mkp(x) result(p) + real, intent(in) :: x + type(pt_t) :: p + ncalls = ncalls + 1 + p%x = x + end function + + function mkc(k) result(c) + integer, intent(in) :: k + class(base_t), allocatable :: c + ncalls = ncalls + 1 + allocate(child_t :: c) + c%k = k + end function + + function dminus(a, b) result(d) + class(div_t), intent(in) :: a, b + type(div_t) :: d + d%v = a%v - b%v + end function + + function dneg(a) result(d) + class(div_t), intent(in) :: a + type(div_t) :: d + d%v = -a%v + end function + + function dplus(a, b) result(d) + type(div_t), intent(in) :: a, b + type(div_t) :: d + d%v = a%v + b%v + end function + + function vdiv(self) result(d) + class(vec_t), intent(in) :: self + type(div_t) :: d + ncalls = ncalls + 1 + d%v = 2*self%v + end function + + subroutine assign_div(lhs, rhs) + class(sc_t), intent(inout) :: lhs + type(div_t), intent(in) :: rhs + if (allocated(lhs%v)) deallocate(lhs%v) + allocate(lhs%v, source=rhs%v) + end subroutine + + function padd(a, b) result(p) + class(pt_t), intent(in) :: a, b + type(pt_t) :: p + p%x = a%x + b%x + end function + + function bmul(a, b) result(r) + class(base_t), intent(in) :: a, b + integer :: r + r = a%k * b%k + end function + + function cmul(a, b) result(r) + class(child_t), intent(in) :: a + class(base_t), intent(in) :: b + integer :: r + r = 10 * a%k * b%k + end function + + function badd(a, b) result(r) + class(base_t), intent(in) :: a, b + type(base_t) :: r + r%k = a%k + b%k + end function + + function cadd(a, b) result(r) + class(child_t), intent(in) :: a + class(base_t), intent(in) :: b + type(base_t) :: r + r%k = 100 + a%k + b%k + end function + +end module + +program operator_overloading_46 + use operator_overloading_46_mod + implicit none + type(div_t) :: r + type(vec_t) :: a, b + type(sc_t) :: s + type(pt_t) :: p + type(base_t) :: q + integer :: k + + ncalls = 0 + r = mk(3.) - mk(1.) + print *, ncalls, r%v + if (ncalls /= 2) error stop + if (any(abs(r%v - 2.) > 1e-6)) error stop + + ncalls = 0 + r = .neg. mk(3.) + print *, ncalls, r%v + if (ncalls /= 1) error stop + if (any(abs(r%v + 3.) > 1e-6)) error stop + + ncalls = 0 + r = mk(3.) + mk(1.) + print *, ncalls, r%v + if (ncalls /= 2) error stop + if (any(abs(r%v - 4.) > 1e-6)) error stop + + ncalls = 0 + r = mk(5.) - mk(2.) - mk(1.) + print *, ncalls, r%v + if (ncalls /= 3) error stop + if (any(abs(r%v - 2.) > 1e-6)) error stop + + allocate(a%v(3), b%v(3)) + a%v = [1., 2., 3.] + b%v = [5., 5., 5.] + ncalls = 0 + s = .div. a - .div. b + print *, ncalls, s%v + if (ncalls /= 2) error stop + if (any(abs(s%v - [-8., -6., -4.]) > 1e-6)) error stop + + ncalls = 0 + p = mkp(3.) + mkp(1.) + print *, ncalls, p%x + if (ncalls /= 2) error stop + if (abs(p%x - 4.) > 1e-6) error stop + + ncalls = 0 + k = mkc(2) * mkc(3) + print *, ncalls, k + if (ncalls /= 2) error stop + if (k /= 60) error stop + + ncalls = 0 + q = mkc(2) + mkc(3) + print *, ncalls, q%k + if (ncalls /= 2) error stop + if (q%k /= 105) error stop +end program diff --git a/src/bin/CMakeLists.txt b/src/bin/CMakeLists.txt index 9833a3998c6..2f800b69a33 100644 --- a/src/bin/CMakeLists.txt +++ b/src/bin/CMakeLists.txt @@ -26,6 +26,7 @@ endif() set(LFORTRAN_SRC lfortran_accessor.cpp lsp_cli.cpp + cuda_link_helpers.cpp ${LFORTRAN_SRC} ) diff --git a/src/bin/cuda_link_helpers.cpp b/src/bin/cuda_link_helpers.cpp new file mode 100644 index 00000000000..d41a1895dc5 --- /dev/null +++ b/src/bin/cuda_link_helpers.cpp @@ -0,0 +1,301 @@ +#include "cuda_link_helpers.h" + +#include +#include +#include +#include +#include + +#include + +#ifdef HAVE_LFORTRAN_LLVM +#include +#include +#include +#include +#include +#include +#endif + +namespace { + +bool append_cuda_sidecar( + const std::filesystem::path &sidecar, + std::set &seen_sidecars, + std::vector &cuda_sources) +{ + if (!seen_sidecars.insert(sidecar.string()).second) { + return true; + } + std::error_code ec; + if (!std::filesystem::exists(sidecar, ec)) { + if (ec) { + std::cerr << "Failed to inspect CUDA sidecar '" << sidecar + << "': " << ec.message() << std::endl; + return false; + } + return true; + } + if (!std::filesystem::is_regular_file(sidecar, ec)) { + if (ec) { + std::cerr << "Failed to inspect CUDA sidecar '" << sidecar + << "': " << ec.message() << std::endl; + } else { + std::cerr << "CUDA sidecar '" << sidecar + << "' is not a regular file" << std::endl; + } + return false; + } + + std::string sidecar_source; + if (!LCompilers::read_file(sidecar.string(), sidecar_source)) { + std::cerr << "Failed to read CUDA sidecar '" << sidecar << "'" + << std::endl; + return false; + } + cuda_sources.push_back(std::move(sidecar_source)); + return true; +} + +#ifdef HAVE_LFORTRAN_LLVM +llvm::Expected cuda_section_name( + const llvm::object::SectionRef §ion) +{ +#if LLVM_VERSION_MAJOR >= 10 + return section.getName(); +#else + llvm::StringRef name; + if (auto error = section.getName(name)) { + return llvm::errorCodeToError(error); + } + return name; +#endif +} + +llvm::Expected cuda_section_contents( + const llvm::object::SectionRef §ion) +{ +#if LLVM_VERSION_MAJOR >= 9 + return section.getContents(); +#else + llvm::StringRef contents; + if (auto error = section.getContents(contents)) { + return llvm::errorCodeToError(error); + } + return contents; +#endif +} + +const char *cuda_source_section_name() +{ +#ifdef HAVE_LFORTRAN_MACHO + return "__lcgpu"; +#else + return ".lcompilers.gpu.cuda.source"; +#endif +} + +bool append_cuda_payload( + const char *data, + size_t size, + std::vector &cuda_sources) +{ + size_t pos = 0; + while (pos < size) { + size_t end = pos; + while (end < size && data[end] != '\0') { + end++; + } + if (end == size) { + std::cerr << "Malformed CUDA metadata: missing NUL terminator" + << std::endl; + return false; + } + if (end > pos) { + cuda_sources.emplace_back(data + pos, end - pos); + } + pos = end + 1; + while (pos < size && data[pos] == '\0') { + pos++; + } + } + return true; +} + +bool append_cuda_section_from_object( + llvm::object::ObjectFile &object, + std::vector &cuda_sources, + bool &found_cuda_section) +{ + for (const auto §ion : object.sections()) { + auto section_name_or_err = cuda_section_name(section); + if (!section_name_or_err) { + std::cerr << "Failed to read CUDA section name: " + << llvm::toString(section_name_or_err.takeError()) + << std::endl; + return false; + } + if (*section_name_or_err != cuda_source_section_name()) { + continue; + } + found_cuda_section = true; + auto contents_or_err = cuda_section_contents(section); + if (!contents_or_err) { + std::cerr << "Failed to read CUDA section contents: " + << llvm::toString(contents_or_err.takeError()) + << std::endl; + return false; + } + if (!append_cuda_payload(contents_or_err->data(), + contents_or_err->size(), cuda_sources)) { + return false; + } + } + return true; +} + +bool append_cuda_source_from_input_impl( + const std::string &input, + std::set &seen_sidecars, + std::vector &cuda_sources) +{ + auto binary_or_err = llvm::object::createBinary(input); + if (!binary_or_err) { + std::cerr << "Failed to open linker input '" << input << "': " + << llvm::toString(binary_or_err.takeError()) << std::endl; + return false; + } + bool found_cuda_section = false; + llvm::object::Binary *binary = binary_or_err->getBinary(); + if (auto *object = llvm::dyn_cast(binary)) { + if (!append_cuda_section_from_object(*object, cuda_sources, + found_cuda_section)) { + return false; + } + } else if (auto *archive = llvm::dyn_cast(binary)) { + llvm::Error err = llvm::Error::success(); + for (auto child : archive->children(err)) { + auto child_binary_or_err = child.getAsBinary(); + if (!child_binary_or_err) { + std::cerr << "Failed to open archive member binary: " + << llvm::toString(child_binary_or_err.takeError()) + << std::endl; + return false; + } + if (auto *child_object = llvm::dyn_cast( + child_binary_or_err->get())) { + bool child_found_cuda_section = false; + if (!append_cuda_section_from_object(*child_object, + cuda_sources, child_found_cuda_section)) { + return false; + } + found_cuda_section = found_cuda_section || child_found_cuda_section; + } + } + if (err) { + std::cerr << "Failed to read archive member list: " + << llvm::toString(std::move(err)) << std::endl; + return false; + } + } + if (!found_cuda_section) { + return append_cuda_sidecar( + std::filesystem::path(input + ".cuda.cu"), + seen_sidecars, cuda_sources); + } + return true; +} +#else +bool append_cuda_source_from_input_impl( + const std::string &input, + std::set &seen_sidecars, + std::vector &cuda_sources) +{ + return append_cuda_sidecar( + std::filesystem::path(input + ".cuda.cu"), + seen_sidecars, cuda_sources); +} +#endif + +} // namespace + +bool append_cuda_source_from_input( + const std::string &input, + std::set &seen_sidecars, + std::vector &cuda_sources) +{ + return append_cuda_source_from_input_impl( + input, seen_sidecars, cuda_sources); +} + +bool resolve_linker_library( + const std::string &library_name, + const std::vector &lib_dirs, + LCompilers::Platform platform, + bool static_only, + std::filesystem::path &resolved_path, + bool &is_static_archive) +{ + std::vector shared_suffixes; + if (platform == LCompilers::Platform::macOS_Intel || + platform == LCompilers::Platform::macOS_ARM || + platform == LCompilers::Platform::macOS_PowerPC) { + shared_suffixes = {".dylib", ".so", ".tbd"}; + } else if (platform == LCompilers::Platform::Windows) { + shared_suffixes = {".dll"}; + } else { + shared_suffixes = {".so"}; + } + const std::vector static_suffixes = + (platform == LCompilers::Platform::Windows) ? + std::vector{".lib"} : + std::vector{".a"}; + const std::string library_prefix = + (platform == LCompilers::Platform::Windows) ? "" : "lib"; + + for (const auto &dir : lib_dirs) { + const std::filesystem::path base_dir(dir); + if (!static_only) { + for (const auto &suffix : shared_suffixes) { + const std::filesystem::path candidate = + base_dir / (library_prefix + library_name + suffix); + std::error_code ec; + if (std::filesystem::is_regular_file(candidate, ec) && !ec) { + resolved_path = candidate; + is_static_archive = false; + return true; + } + } + } + for (const auto &suffix : static_suffixes) { + const std::filesystem::path candidate = + base_dir / (library_prefix + library_name + suffix); + std::error_code ec; + if (std::filesystem::is_regular_file(candidate, ec) && !ec) { + resolved_path = candidate; + is_static_archive = true; + return true; + } + } + } + return false; +} + +bool append_cuda_source_from_library( + const std::string &library_name, + const std::vector &lib_dirs, + LCompilers::Platform platform, + bool static_only, + std::set &seen_sidecars, + std::vector &cuda_sources) +{ + std::filesystem::path resolved_library; + bool is_static_archive = false; + if (!resolve_linker_library(library_name, lib_dirs, platform, static_only, + resolved_library, is_static_archive)) { + return true; + } + if (!is_static_archive) return true; + return append_cuda_source_from_input(resolved_library.string(), + seen_sidecars, cuda_sources); +} diff --git a/src/bin/cuda_link_helpers.h b/src/bin/cuda_link_helpers.h new file mode 100644 index 00000000000..f660c54bd06 --- /dev/null +++ b/src/bin/cuda_link_helpers.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include +#include + +#include "libasr/utils.h" + +bool resolve_linker_library( + const std::string &library_name, + const std::vector &lib_dirs, + LCompilers::Platform platform, + bool static_only, + std::filesystem::path &resolved_path, + bool &is_static_archive); + +bool append_cuda_source_from_library( + const std::string &library_name, + const std::vector &lib_dirs, + LCompilers::Platform platform, + bool static_only, + std::set &seen_sidecars, + std::vector &cuda_sources); + +bool append_cuda_source_from_input( + const std::string &input, + std::set &seen_sidecars, + std::vector &cuda_sources); diff --git a/src/bin/lfortran.cpp b/src/bin/lfortran.cpp index df3ffce4fc9..6b6b8267b3f 100644 --- a/src/bin/lfortran.cpp +++ b/src/bin/lfortran.cpp @@ -4,11 +4,14 @@ #include #include #include +#include #include +#include #ifndef CLI11_HAS_FILESYSTEM #define CLI11_HAS_FILESYSTEM 0 #endif // CLI11_HAS_FILESYSTEM #include +#include "cuda_link_helpers.h" #include #include @@ -53,6 +56,13 @@ #include #include #include +#ifdef HAVE_LFORTRAN_LLVM +#include +#include +#include +#include +#include +#endif #include #include #include @@ -91,6 +101,7 @@ namespace { using LCompilers::endswith; using LCompilers::CompilerOptions; +using LCompilers::read_file; using LCompilers::read_file_ok; namespace lcli = LCompilers::CommandLineInterface; @@ -118,8 +129,6 @@ std::string get_system_temp_dir() std::string LFORTRAN_TEMP_DIR = get_system_temp_dir(); - - // The unique compilation ID for this invocation of the compiler. // Used in naming unique intermediate object files during both compilation modes. const std::string LCOMPILERS_UNIQUE_ID = LCompilers::get_unique_ID(); @@ -2112,6 +2121,10 @@ int link_executable(const std::vector &infiles, std::cout << "Cannot use static_executable and shared_executable together" << std::endl; return 10; } + const bool static_library_search = static_executable + && compiler_options.platform != LCompilers::Platform::macOS_Intel + && compiler_options.platform != LCompilers::Platform::macOS_ARM + && compiler_options.platform != LCompilers::Platform::macOS_PowerPC; if (backend == Backend::llvm || backend == Backend::mlir) { std::string run_cmd = "", compile_cmd = ""; if (t == "x86_64-pc-windows-msvc") { @@ -2207,7 +2220,7 @@ int link_executable(const std::vector &infiles, if(!extra_library_flags.empty()) { compile_cmd += extra_library_flags + " "; } - compile_cmd += + " -L" + compile_cmd += " -L" + base_path + " -Wl,-rpath," + base_path; if (!extra_linker_flags.empty()) { compile_cmd += extra_linker_flags; @@ -2239,57 +2252,84 @@ int link_executable(const std::vector &infiles, + " -framework Metal -framework Foundation"; } if (compiler_options.gpu_backend == "cuda") { - // Collect CUDA kernel source. Every object file carries the - // device source of its own translation unit in a sidecar, so - // reading all of them is what picks up a kernel that lives in - // a module compiled separately. Only a link that finds no - // sidecar at all falls back to the source this invocation - // generated. - std::string cuda_source; + // Collect CUDA kernel source from embedded object metadata. + // Each object contributes its own translation unit, and + // legacy sidecars remain as a fallback for older builds. + std::vector cuda_sources; + std::set seen_cuda_sidecars; for (auto &s : infiles) { - std::string sidecar = s + ".cuda.cu"; - std::ifstream f(sidecar); - if (f.good()) { - std::string content( - (std::istreambuf_iterator(f)), - std::istreambuf_iterator()); - cuda_source += content; + if (!append_cuda_source_from_input( + s, seen_cuda_sidecars, cuda_sources)) { + return 10; } } - if (cuda_source.empty()) { - cuda_source = compiler_options.gpu_cuda_source; + for (auto &library_name : libraries) { + if (!append_cuda_source_from_library(library_name, lib_dirs, + compiler_options.platform, static_library_search, + seen_cuda_sidecars, cuda_sources)) { + return 10; + } } - - // Write CUDA kernel source to a temp .cu file - std::string cuda_kernel_src = LFORTRAN_TEMP_DIR - + "/lfortran_gpu_kernel_" + LCOMPILERS_UNIQUE_ID + ".cu"; - std::string cuda_kernel_obj = LFORTRAN_TEMP_DIR - + "/lfortran_gpu_kernel_" + LCOMPILERS_UNIQUE_ID + ".o"; - { - std::ofstream cu_out(cuda_kernel_src); - cu_out << cuda_source; - cu_out.close(); + if (cuda_sources.empty()) { + cuda_sources.push_back(compiler_options.gpu_cuda_source); } - // Compile the kernel .cu with the device compiler. When - // emulating, the device code is ordinary host C++, and the - // language has to be named explicitly because no host - // compiler knows the .cu suffix. The emulation is built - // without OpenMP, so the threads of a block run one after - // another and a __syncthreads() reports that it cannot be - // honoured; the device code and the runtime below have to - // agree on that, so neither is given -fopenmp. + + // Write every unique CUDA fragment to a temp .cu file. Each + // translation unit compiles separately so its local + // declarations stay local and identical definitions do not + // collide when archive members are aggregated at link time. bool emulate_cpu = compiler_options.gpu_cpu_emulation; std::string runtime_include = " -I" + runtime_library_dir + "/../libasr/runtime"; std::string device_cc = compiler_options.device_compiler; - std::string cuda_kernel_cmd = device_cc + " -c -O2" - + (emulate_cpu ? runtime_include + " -x c++" : "") - + " -o " + cuda_kernel_obj + " " + cuda_kernel_src; - int cuda_err = system(cuda_kernel_cmd.c_str()); - if (cuda_err) { - std::cerr << "Failed to compile CUDA kernel: " - << cuda_kernel_cmd << std::endl; - return 10; + if (!emulate_cpu) { + // Without an architecture nvcc builds for its oldest + // default one, which a newer GPU can run only by JIT + // compiling the embedded PTX at startup. `native` builds + // for the GPUs present, and falls back to the default + // with a warning on a machine that has none. Kernel, + // runtime and link all go through device_cc, so they + // agree on it. + device_cc += " -arch=" + (compiler_options.gpu_arch.empty() + ? std::string("native") : compiler_options.gpu_arch); + } + std::vector cuda_kernel_objs; + std::set seen_cuda_fragments; + size_t cuda_kernel_index = 0; + for (const auto &cuda_source : cuda_sources) { + if (!seen_cuda_fragments.insert(cuda_source).second) { + continue; + } + std::string cuda_kernel_src = LFORTRAN_TEMP_DIR + + "/lfortran_gpu_kernel_" + LCOMPILERS_UNIQUE_ID + + "_" + std::to_string(cuda_kernel_index) + ".cu"; + std::string cuda_kernel_obj = LFORTRAN_TEMP_DIR + + "/lfortran_gpu_kernel_" + LCOMPILERS_UNIQUE_ID + + "_" + std::to_string(cuda_kernel_index) + ".o"; + { + std::ofstream cu_out(cuda_kernel_src); + cu_out << cuda_source; + cu_out.close(); + } + // Compile the kernel .cu with the device compiler. When + // emulating, the device code is ordinary host C++, and + // the language has to be named explicitly because no host + // compiler knows the .cu suffix. The emulation is built + // without OpenMP, so the threads of a block run one after + // another and a __syncthreads() reports that it cannot be + // honoured; the device code and the runtime below have to + // agree on that, so neither is given -fopenmp. + std::string cuda_kernel_cmd = device_cc + " -c -O2" + + (emulate_cpu ? runtime_include + " -x c++" : "") + + " -o " + cuda_kernel_obj + " " + cuda_kernel_src; + int cuda_err = system(cuda_kernel_cmd.c_str()); + if (cuda_err) { + std::cerr << "Failed to compile CUDA kernel: " + << cuda_kernel_cmd << std::endl; + return 10; + } + cuda_kernel_objs.push_back(std::move(cuda_kernel_obj)); + cuda_kernel_index++; } // Compile the GPU runtime. The CPU emulation uses its own @@ -2307,7 +2347,7 @@ int link_executable(const std::vector &infiles, + (emulate_cpu ? " -x c" : "") + " -o " + cuda_runtime_obj + " " + cuda_runtime_src; - cuda_err = system(cuda_rt_cmd.c_str()); + int cuda_err = system(cuda_rt_cmd.c_str()); if (cuda_err) { std::cerr << "Failed to compile CUDA runtime: " << cuda_rt_cmd << std::endl; @@ -2328,17 +2368,25 @@ int link_executable(const std::vector &infiles, == LCompilers::Platform::macOS_ARM || compiler_options.platform == LCompilers::Platform::macOS_PowerPC; - compile_cmd += " " + cuda_kernel_obj - + " " + cuda_runtime_obj + for (auto &cuda_kernel_obj : cuda_kernel_objs) { + compile_cmd += " " + cuda_kernel_obj; + } + compile_cmd += " " + cuda_runtime_obj + (is_macos ? " -lc++" : " -lstdc++") + " -lm"; } else { // The device compiler also drives the link, since it knows // where its own device runtime lives. - compile_cmd = device_cc + " -o " + outfile + " "; + compile_cmd = device_cc + + (static_library_search ? " -Xcompiler=-static" : "") + + " -o " + outfile + " "; for (auto &s : infiles) { compile_cmd += s + " "; } - compile_cmd += cuda_kernel_obj + " " + cuda_runtime_obj; + for (auto &cuda_kernel_obj : cuda_kernel_objs) { + compile_cmd += cuda_kernel_obj + " "; + } + compile_cmd += cuda_runtime_obj; + compile_cmd += extra_library_flags; compile_cmd += " -L" + base_path + " -Xlinker -rpath -Xlinker " + base_path + " -l" + runtime_lib + " -lm"; diff --git a/src/bin/lfortran_command_line_parser.cpp b/src/bin/lfortran_command_line_parser.cpp index 6d1958ed210..4278c65c165 100644 --- a/src/bin/lfortran_command_line_parser.cpp +++ b/src/bin/lfortran_command_line_parser.cpp @@ -350,6 +350,7 @@ namespace LCompilers::CommandLineInterface { app.add_option("--emcc-embed", compiler_options.emcc_embed, "Embed a given file/directory using emscripten for LLVM->WASM")->group(group_backend_codegen_options); app.add_option("--gpu", compiler_options.gpu_backend, "Enable GPU offloading for do concurrent (metal, cuda, cuda_cpu)")->capture_default_str()->group(group_backend_codegen_options); app.add_option("--device-compiler", compiler_options.device_compiler, "Toolchain driver used to compile and link GPU device code")->capture_default_str()->group(group_backend_codegen_options); + app.add_option("--gpu-arch", compiler_options.gpu_arch, "GPU architecture to compile device code for with --gpu=cuda (e.g. sm_120); defaults to the GPUs of the compiling machine")->group(group_backend_codegen_options); app.add_flag("--gpu-offload-omp-loops", compiler_options.po.gpu_offload_omp_loops, "Offload an `!$omp parallel do` loop onto the GPU as well")->group(group_backend_codegen_options); app.add_flag("--gpu-allow-cpu-fallback", compiler_options.po.gpu_allow_cpu_fallback, "Run a parallel loop that uses a construct the selected GPU does not support (real(8) on Metal, real(10) or real(16), or input/output) on the CPU with a warning instead of failing compilation")->group(group_backend_codegen_options); diff --git a/src/lfortran/tests/CMakeLists.txt b/src/lfortran/tests/CMakeLists.txt index d23708481a2..63f8705a072 100644 --- a/src/lfortran/tests/CMakeLists.txt +++ b/src/lfortran/tests/CMakeLists.txt @@ -27,6 +27,18 @@ if (NOT XEUS_LFORTRAN_WASM_BUILD) ADDTEST(test_stacktrace) endif() +add_library(cuda_link_helper_plain_fixture STATIC plain.c) +set_target_properties(cuda_link_helper_plain_fixture PROPERTIES OUTPUT_NAME plain) +set(cuda_link_helpers_fixture_header_content [=[ +#pragma once +namespace cuda_link_helpers_fixture { +inline constexpr const char plain_archive[] = R"PATH($)PATH"; +inline constexpr const char plain_member[] = "plain.c@CMAKE_C_OUTPUT_EXTENSION@"; +} +]=]) +string(CONFIGURE "${cuda_link_helpers_fixture_header_content}" cuda_link_helpers_fixture_header_content @ONLY) +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/$/test_cuda_link_helpers_fixture.hpp" CONTENT "${cuda_link_helpers_fixture_header_content}") + set(SRC test_parse.cpp test_ast.cpp @@ -38,6 +50,8 @@ set(SRC test_asr_text.cpp test_asr_text_parser.cpp test_gpu.cpp + ../../bin/cuda_link_helpers.cpp + ../../tests/test_cuda_link_helpers.cpp ) if (WITH_JSON) @@ -68,6 +82,8 @@ endif() add_executable(test_lfortran ${SRC}) target_link_libraries(test_lfortran lfortran_lib p::doctest) target_compile_definitions(test_lfortran PRIVATE LFORTRAN_PROJECT_SOURCE_DIR="${CMAKE_SOURCE_DIR}") +target_include_directories(test_lfortran PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/$") +add_dependencies(test_lfortran cuda_link_helper_plain_fixture) # The test binary never calls set_exec_path_and_mode(), so it cannot work out # where the runtime modfiles are; a test that uses an intrinsic module would # fail with "modfile was not found". Under Emscripten they are preloaded into diff --git a/src/lfortran/tests/plain.c b/src/lfortran/tests/plain.c new file mode 100644 index 00000000000..ec6c6c906c3 --- /dev/null +++ b/src/lfortran/tests/plain.c @@ -0,0 +1,4 @@ +int plain(void) +{ + return 7; +} diff --git a/src/libasr/codegen/asr_to_cuda.cpp b/src/libasr/codegen/asr_to_cuda.cpp index 57c46cc8146..0cfadaea9b3 100644 --- a/src/libasr/codegen/asr_to_cuda.cpp +++ b/src/libasr/codegen/asr_to_cuda.cpp @@ -160,10 +160,9 @@ struct CudaDialect { void emit_translation_unit_epilogue(std::stringstream &src, const std::vector &kernel_names) const { - if (!emit_registrar) return; + if (!emit_registrar || kernel_names.empty()) return; src << "\n// Auto-generated kernel registration\n"; if (emulate_cpu) { - if (kernel_names.empty()) return; // The thunks are registered instead of the kernels, and a plain // constructor attribute keeps the file free of any C++ runtime // dependency. Under separate compilation the per-object device @@ -182,17 +181,25 @@ struct CudaDialect { src << "}\n"; return; } + if (kernel_names.empty()) return; src << "typedef void (*kernel_func_t)(void);\n"; src << "extern \"C\" void lfortran_gpu_register_kernel(" "const char *name, kernel_func_t func);\n\n"; - src << "struct _lfortran_cuda_registrar {\n"; - src << " _lfortran_cuda_registrar() {\n"; + // As above, the registrar is named after the first kernel so that + // the concatenated per-object device sources do not collide; the + // anonymous namespace also keeps it local to its translation unit. + const std::string registrar = "_lfortran_cuda_registrar_" + + kernel_names[0]; + src << "namespace {\n"; + src << "struct " << registrar << " {\n"; + src << " " << registrar << "() {\n"; for (auto &kname : kernel_names) { src << " lfortran_gpu_register_kernel(\"" << kname << "\", (kernel_func_t)" << kname << ");\n"; } src << " }\n"; - src << "} _lfortran_cuda_reg;\n"; + src << "} " << registrar << "_instance;\n"; + src << "}\n"; } }; diff --git a/src/libasr/codegen/asr_to_gpu_c.h b/src/libasr/codegen/asr_to_gpu_c.h index 0d918b05a40..a0543a7f616 100644 --- a/src/libasr/codegen/asr_to_gpu_c.h +++ b/src/libasr/codegen/asr_to_gpu_c.h @@ -618,6 +618,10 @@ class ASRToGpuCVisitor // host runtime binds them. A dialect epilogue reads this back. std::vector kernel_params; + // What the kernel being emitted declares ahead of its body, which it + // writes once the body shows which of them it refers to. + std::vector kernel_declarations; + // The spellings this instantiation emits. It is a value rather than a // set of static members so that a dialect can carry per-invocation state, // such as whether the CUDA backend is emitting for the CPU emulation. @@ -3440,6 +3444,8 @@ class ASRToGpuCVisitor ASR::down_cast(fn->m_return_var)->m_v); src << get_indent() << ret_type << " " << sanitize_name(rv->m_name) << ";\n"; } + // The function writes only the declarations its body refers to. + std::vector declarations; // Declare Parameter (constant) variables from the function scope for (auto &item : fn->m_symtab->get_scope()) { if (!ASR::is_a(*item.second)) continue; @@ -3447,7 +3453,8 @@ class ASRToGpuCVisitor item.second); if (var->m_storage != ASR::storage_typeType::Parameter) continue; if (!var->m_value) continue; - emit_named_constant_decl(var); + declarations.push_back(variable_declaration(*var, + [&]() { emit_named_constant_decl(var); })); } // Declare local variables (non-argument, non-return, non-parameter) in_inline_function = true; @@ -3470,7 +3477,8 @@ class ASRToGpuCVisitor if (var->m_storage == ASR::storage_typeType::Parameter) continue; if (declared_by_signature.count(item.second)) continue; - emit_local_var_decl(var); + declarations.push_back(variable_declaration(*var, + [&]() { emit_local_var_decl(var); })); } } // Pre-scan the inline function body for Allocate statements @@ -3580,9 +3588,12 @@ class ASRToGpuCVisitor ASR::down_cast(fn->m_return_var)->m_v) ->m_name); } - for (size_t i = 0; i < fn->n_body; i++) { - visit_stmt(fn->m_body[i]); - } + std::string body = captured_source([&]() { + for (size_t i = 0; i < fn->n_body; i++) { + visit_stmt(fn->m_body[i]); + } + }); + src << gpu_referenced_declarations(declarations, body) << body; current_return_name.clear(); in_inline_function = false; if (fn->m_return_var) { @@ -3604,6 +3615,23 @@ class ASRToGpuCVisitor current_kernel_layout = nullptr; } + // What `emit` writes to `src`, which it leaves as it was. + template + std::string captured_source(F emit) { + std::stringstream saved; + saved.swap(src); + emit(); + saved.swap(src); + return saved.str(); + } + + // The declaration `emit` writes for `var`. + template + GpuDeclaration variable_declaration(const ASR::Variable_t &var, F emit) { + std::string name(var.m_name); + return {{name, sanitize_name(name)}, captured_source(emit)}; + } + void emit_kernel_signature(const ASR::Function_t &x); void bind_kernel_arguments(const ASR::Function_t &x); @@ -3656,12 +3684,18 @@ class ASRToGpuCVisitor } for (ASR::Variable_t *var : gpu_scope_declaration_order( x.m_symtab, current_vla_infos, arg_names)) { - emit_local_var_decl(var); + kernel_declarations.push_back(variable_declaration(*var, + [&]() { emit_local_var_decl(var); })); } - for (size_t i = 0; i < x.n_body; i++) { - visit_stmt(x.m_body[i]); - } + std::string body = captured_source([&]() { + for (size_t i = 0; i < x.n_body; i++) { + visit_stmt(x.m_body[i]); + } + }); + src << gpu_referenced_declarations(kernel_declarations, body) + << body; + kernel_declarations.clear(); indent_level--; src << "}\n\n"; @@ -4402,59 +4436,68 @@ class ASRToGpuCVisitor BlockNameScope block_names(*this, block->m_symtab); src << get_indent() << "{\n"; indent_level++; + // The block writes only the declarations its body refers to. + std::vector declarations; for (ASR::Variable_t *v : gpu_scope_declaration_order( block->m_symtab, current_vla_infos)) { - // Check if this variable is a VLA backed by a workspace - // buffer (populated during kernel signature generation). - std::string vname(v->m_name); - auto vla_it = std::find_if( - current_vla_infos.begin(), current_vla_infos.end(), - [&](const GpuVlaWorkspace &ws) { - return ws.var == &v->base; - }); - if (vla_it != current_vla_infos.end()) { - std::string elem_type_str; - ASR::ttype_t *vtype = - ASRUtils::type_get_past_allocatable(v->m_type); - if (ASR::is_a(*vtype)) { - elem_type_str = gpu_type( - ASR::down_cast( - vtype)->m_type); - } - if (elem_type_str.empty() - || elem_type_str.find("unsupported") - != std::string::npos) { - throw CodeGenError( - "gpu offload: workspace '" + vname + - "' has no gpu type of the same width"); - } - // Emit a device pointer into the per-thread slice - std::string extent = - workspace_extent_str(*vla_it); - std::string slice = workspace_slice_str(*vla_it); - src << get_indent() << global_prefix() - << elem_type_str << "* " << vname - << " = " << gpu_workspace_buffer_name( - vla_it->buffer_index) - << " + " << dialect.global_thread_id() - << " * "; - if (vla_it->dims.size() == 1) { - src << slice; + declarations.push_back(variable_declaration(*v, [&]() { + // Check if this variable is a VLA backed by a + // workspace buffer (populated during kernel + // signature generation). + std::string vname(v->m_name); + auto vla_it = std::find_if( + current_vla_infos.begin(), current_vla_infos.end(), + [&](const GpuVlaWorkspace &ws) { + return ws.var == &v->base; + }); + if (vla_it != current_vla_infos.end()) { + std::string elem_type_str; + ASR::ttype_t *vtype = + ASRUtils::type_get_past_allocatable(v->m_type); + if (ASR::is_a(*vtype)) { + elem_type_str = gpu_type( + ASR::down_cast( + vtype)->m_type); + } + if (elem_type_str.empty() + || elem_type_str.find("unsupported") + != std::string::npos) { + throw CodeGenError( + "gpu offload: workspace '" + vname + + "' has no gpu type of the same width"); + } + // Emit a device pointer into the per-thread slice + std::string extent = + workspace_extent_str(*vla_it); + std::string slice = workspace_slice_str(*vla_it); + src << get_indent() << global_prefix() + << elem_type_str << "* " << vname + << " = " << gpu_workspace_buffer_name( + vla_it->buffer_index) + << " + " << dialect.global_thread_id() + << " * "; + if (vla_it->dims.size() == 1) { + src << slice; + } else { + src << "(" << slice << ")"; + } + src << ";\n"; + local_alloc_arrays.insert(&v->base); + // Record the size expression for alloc-assign + // and copy-loop codegen + alloc_array_size_exprs[vname] = extent; } else { - src << "(" << slice << ")"; + emit_local_var_decl(v); } - src << ";\n"; - local_alloc_arrays.insert(&v->base); - // Record the size expression for alloc-assign - // and copy-loop codegen - alloc_array_size_exprs[vname] = extent; - } else { - emit_local_var_decl(v); - } - } - for (size_t i = 0; i < block->n_body; i++) { - visit_stmt(block->m_body[i]); + })); } + std::string body = captured_source([&]() { + for (size_t i = 0; i < block->n_body; i++) { + visit_stmt(block->m_body[i]); + } + }); + src << gpu_referenced_declarations(declarations, body) + << body; indent_level--; src << get_indent() << "}\n"; break; @@ -4468,13 +4511,19 @@ class ASRToGpuCVisitor BlockNameScope block_names(*this, ab->m_symtab); src << get_indent() << "{\n"; indent_level++; + std::vector declarations; for (ASR::Variable_t *v : gpu_scope_declaration_order( ab->m_symtab, current_vla_infos)) { - emit_local_var_decl(v); - } - for (size_t i = 0; i < ab->n_body; i++) { - visit_stmt(ab->m_body[i]); + declarations.push_back(variable_declaration(*v, + [&]() { emit_local_var_decl(v); })); } + std::string body = captured_source([&]() { + for (size_t i = 0; i < ab->n_body; i++) { + visit_stmt(ab->m_body[i]); + } + }); + src << gpu_referenced_declarations(declarations, body) + << body; indent_level--; src << get_indent() << "}\n"; break; diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index 73cd4048814..ff76682a1f5 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -2534,6 +2534,29 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm::appendToGlobalCtors(*module, ctor_fn, 65535); } + void emit_gpu_cuda_source_section() { + if (compiler_options.gpu_cuda_source.empty()) return; + const char *cuda_source_section_name = +#ifdef HAVE_LFORTRAN_MACHO + "__DATA,__lcgpu"; +#else + ".lcompilers.gpu.cuda.source"; +#endif + std::string framed_source = compiler_options.gpu_cuda_source; + framed_source.push_back('\0'); + llvm::ArrayType *source_type = llvm::ArrayType::get( + llvm::Type::getInt8Ty(context), + framed_source.size()); + auto *source = new llvm::GlobalVariable( + *module, source_type, true, llvm::GlobalValue::PrivateLinkage, + llvm::ConstantDataArray::getString(context, framed_source, false), + "__lcompilers_gpu_cuda_source"); + source->setSection(cuda_source_section_name); + source->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); + source->setAlignment(llvm::Align(1)); + llvm::appendToCompilerUsed(*module, {source}); + } + template void visit_AllocateUtil(const T& x, ASR::expr_t* m_stat, bool realloc, ASR::expr_t* m_source = nullptr) { llvm::Value* stat_target = nullptr; @@ -30097,8 +30120,11 @@ Result> asr_to_llvm(ASR::TranslationUnit_t &asr, co.gpu_metal_source = metal_res.result; } - // GPU CUDA: generate CUDA kernel source after passes have created the kernel functions - if (co.gpu_backend == "cuda" && co.gpu_cuda_source.empty()) { + // GPU CUDA: generate CUDA kernel source after passes have created the kernel functions. + // Every translation unit needs its own device source; separate compilation reuses + // CompilerOptions across files, so leaving an earlier TU's source in place would + // suppress later kernels and leave their registry empty. + if (co.gpu_backend == "cuda") { diag::Diagnostics cuda_diag; Result cuda_res = asr_to_cuda(al, asr, cuda_diag, co); if (!cuda_res.ok) { @@ -30123,6 +30149,9 @@ Result> asr_to_llvm(ASR::TranslationUnit_t &asr, Error error; return error; } + if (co.gpu_backend == "cuda") { + v.emit_gpu_cuda_source_section(); + } target_config.apply_target_attributes(*v.module); std::string msg; llvm::raw_string_ostream err(msg); diff --git a/src/libasr/codegen/gpu_kernel_signature.h b/src/libasr/codegen/gpu_kernel_signature.h index 57bd016e9d2..2100a657f0c 100644 --- a/src/libasr/codegen/gpu_kernel_signature.h +++ b/src/libasr/codegen/gpu_kernel_signature.h @@ -82,18 +82,24 @@ void ASRToGpuCVisitor::emit_kernel_signature(const ASR::Function_t &kernel) { } src << ")\n{\n"; indent_level++; + // The declarations ahead of the body are collected rather than written, + // so that the kernel writes only those its body refers to. + kernel_declarations.clear(); for (size_t i = 0; i < layout.n_scalars; i++) { const auto &arg = layout.m_scalars[i]; if (arg.m_kind == ASR::gpu_argument_kindType::GpuPackedOffset) continue; std::string parameter = gpu_argument_name(arg, layout); - src << get_indent() << gpu_type(arg.m_type) << " " << parameter - << " = __scalar_args." << parameter << ";\n"; + kernel_declarations.push_back({{parameter}, get_indent() + + gpu_type(arg.m_type) + " " + parameter + + " = __scalar_args." + parameter + ";\n"}); } // Each iteration runs on `lanes` consecutive threads: the thread index // the body sees is the iteration's, and the lane tells them apart. if (layout.m_lanes) { - dialect.emit_lane_prologue(src, get_indent(), + std::stringstream prologue; + dialect.emit_lane_prologue(prologue, get_indent(), ASRUtils::symbol_name(layout.m_lanes)); + kernel_declarations.push_back({{}, prologue.str()}); } if (layout.m_packed) { for (size_t i = 0; i < layout.n_buffers; i++) { @@ -101,11 +107,12 @@ void ASRToGpuCVisitor::emit_kernel_signature(const ASR::Function_t &kernel) { std::string type = element_type(arg); std::string parameter = gpu_argument_name(arg, layout); bool reference = is_reference(arg); - src << get_indent() << global_prefix() << type - << (reference ? "& " : "* ") << parameter << " = " - << (reference ? "*" : "") << "(" << global_prefix() - << type << "*)(__packed_arrays + __scalar_args.__offset_" - << parameter << ");\n"; + kernel_declarations.push_back({{parameter}, get_indent() + + global_prefix() + type + (reference ? "& " : "* ") + + parameter + " = " + (reference ? "*" : "") + "(" + + global_prefix() + type + + "*)(__packed_arrays + __scalar_args.__offset_" + + parameter + ");\n"}); } } } diff --git a/src/libasr/codegen/gpu_utils.h b/src/libasr/codegen/gpu_utils.h index b6f7c4ded92..8f081c83736 100644 --- a/src/libasr/codegen/gpu_utils.h +++ b/src/libasr/codegen/gpu_utils.h @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -361,6 +362,66 @@ struct GpuKernelParam { GpuKernelParamKind kind; }; +// A declaration a kernel, a device function or a block makes ahead of its +// body: a scalar unpacked from the scalar argument struct, a buffer unpacked +// from the packed arrays, or a local variable. It declares the names in +// `names`; one that declares none is always written. +struct GpuDeclaration { + std::vector names; + std::string text; +}; + +// Adds the identifiers the generated source `code` refers to to `result`. +// A member name, which follows `.` or `->`, refers to no variable. +inline void gpu_referenced_identifiers(const std::string &code, + std::set &result) { + auto is_word = [](char c) { + return std::isalnum(static_cast(c)) || c == '_'; + }; + size_t i = 0; + while (i < code.size()) { + if (!is_word(code[i])) { + i++; + continue; + } + size_t start = i; + while (i < code.size() && is_word(code[i])) i++; + if (std::isdigit(static_cast(code[start]))) continue; + bool member = (start >= 1 && code[start - 1] == '.') || + (start >= 2 && code[start - 2] == '-' && code[start - 1] == '>'); + if (!member) result.insert(code.substr(start, i - start)); + } +} + +// The declarations of `declarations` that `body`, or another declaration +// written, refers to, in order. The device compilers warn about a variable +// that is declared and never referred to, so a scope does not unpack the +// scalars or declare the locals it has no use for. Dropping one changes no +// behavior: none has side effects, and the scalar argument struct the host +// fills keeps every field, so the launch is laid out as before. +inline std::string gpu_referenced_declarations( + const std::vector &declarations, + const std::string &body) { + std::set referenced; + gpu_referenced_identifiers(body, referenced); + // A declaration refers only to names declared ahead of it, so walking + // them backwards sees every use of a name before its declaration. + std::vector keep(declarations.size()); + for (size_t i = declarations.size(); i-- > 0;) { + const GpuDeclaration &declaration = declarations[i]; + keep[i] = declaration.names.empty(); + for (const std::string &name : declaration.names) { + keep[i] = keep[i] || referenced.count(name) > 0; + } + if (keep[i]) gpu_referenced_identifiers(declaration.text, referenced); + } + std::string result; + for (size_t i = 0; i < declarations.size(); i++) { + if (keep[i]) result += declarations[i].text; + } + return result; +} + // An allocatable array component of a kernel argument that is an array of a // derived type reaches the device as three buffers: the elements' data laid // out end to end, the per-element offsets into it, and the per-element sizes. diff --git a/src/libasr/pass/array_struct_temporary.cpp b/src/libasr/pass/array_struct_temporary.cpp index c6188d9b432..f369ecf707a 100644 --- a/src/libasr/pass/array_struct_temporary.cpp +++ b/src/libasr/pass/array_struct_temporary.cpp @@ -1670,6 +1670,26 @@ ASR::Variable_t* designator_root_variable(ASR::expr_t* value) { return nullptr; } +// The passed-object actual of a type-bound call is the same expression as the +// dispatch expression `m_dt`, e.g. `mk(3.)` in `mk(3.) - mk(1.)` with a +// type-bound operator. Once the actual `original` has been replaced by +// `prepared`, the dispatch uses `prepared` too, so that the operand is +// evaluated only once. A designator has no side effects and is kept. +ASR::expr_t* passed_object_dispatch(ASR::expr_t* dt, ASR::expr_t* original, + ASR::expr_t* prepared) { + if( dt == nullptr || dt != original || prepared == original ) { + return dt; + } + ASR::expr_t* value = ASRUtils::get_past_array_physical_cast(dt); + if( ASR::is_a(*value) || + ASR::is_a(*value) || + ASR::is_a(*value) || + ASR::is_a(*value) ) { + return dt; + } + return prepared; +} + // A component of an array of derived type, such as `ps%x` or `ps(1::2)%y`, is // a strided section of `ps`: its elements are one struct apart, not one // element apart. It therefore has to be gathered into a contiguous temporary @@ -3541,6 +3561,10 @@ class ReplaceExprWithTemporary: public ASR::BaseExprReplacern_args; i++) { + x->m_dt = passed_object_dispatch(x->m_dt, original_args[i], + x->m_args[i].m_value); + } if (ASRUtils::is_elemental(x->m_name)) { for (size_t i = 0; i < x->n_args; i++) { if (x->m_args[i].m_value && ASRUtils::is_array( diff --git a/src/libasr/pass/array_struct_temporary.h b/src/libasr/pass/array_struct_temporary.h index 120b90b120e..34bc7706b55 100644 --- a/src/libasr/pass/array_struct_temporary.h +++ b/src/libasr/pass/array_struct_temporary.h @@ -20,6 +20,12 @@ namespace LCompilers { ASR::expr_t* value, Vec* current_body, ASR::expr_t* rank_source = nullptr); + // The dispatch expression of a type-bound call after its passed-object + // actual `original`, which is the same expression as `dt`, has been + // replaced by `prepared`, so that the operand is evaluated only once. + ASR::expr_t* passed_object_dispatch(ASR::expr_t* dt, ASR::expr_t* original, + ASR::expr_t* prepared); + void pass_array_struct_temporary(Allocator &al, ASR::TranslationUnit_t &unit, const PassOptions &pass_options); diff --git a/src/libasr/pass/gpu_decline.cpp b/src/libasr/pass/gpu_decline.cpp index 14502d8d44c..800d653224b 100644 --- a/src/libasr/pass/gpu_decline.cpp +++ b/src/libasr/pass/gpu_decline.cpp @@ -167,6 +167,20 @@ std::string gpu_decline_message(const GpuDecline &decline) { case GpuDeclineReason::UnsizedLocalArray: return "local array '" + decline.name + "' has no extent the gpu can use"; + case GpuDeclineReason::LocalityElementType: + return "array '" + decline.name + "' of local locality is of " + "type " + decline.type_name + ", which a gpu thread cannot " + "hold a copy of"; + case GpuDeclineReason::LocalityCoarray: + return "array '" + decline.name + "' of local locality is a " + "coarray, which a gpu thread cannot hold a copy of"; + case GpuDeclineReason::LocalityNamedByAssociate: + return "array '" + decline.name + "' of local locality is " + "named by an associate construct around the loop"; + case GpuDeclineReason::LocalityAssociateNotInlined: + return "array '" + decline.name + "' of local locality cannot " + "be given a copy per gpu thread: the loop body has an " + "associate construct the gpu kernel cannot inline"; case GpuDeclineReason::AliasTemporaryRuntimeSized: return "an aliased assignment needs a run-time sized temporary"; case GpuDeclineReason::UngatherableStridedSection: diff --git a/src/libasr/pass/gpu_decline.h b/src/libasr/pass/gpu_decline.h index 298932ee847..f7e3c3951dd 100644 --- a/src/libasr/pass/gpu_decline.h +++ b/src/libasr/pass/gpu_decline.h @@ -131,6 +131,14 @@ enum class GpuDeclineReason { // --- what the pass's own lowering cannot yet do to the body --- StructElementGather, UnsizedLocalArray, + // An array of LOCAL locality that a thread cannot hold a copy of its + // own of: its type is not one a thread holds as a local, it is a + // coarray, an ASSOCIATE around the loop names it, or the body has an + // ASSOCIATE the kernel cannot inline. + LocalityElementType, + LocalityCoarray, + LocalityNamedByAssociate, + LocalityAssociateNotInlined, AliasTemporaryRuntimeSized, UngatherableStridedSection, // A section passed to a procedure has to be copied into a contiguous @@ -262,6 +270,9 @@ struct GpuDecline { // The element type the decline is about, when the reason is about a // type, which the message names. ASR::ttype_t *type = nullptr; + // The declared type of the variable as the source spells it, for a + // type `type` cannot name by itself (a derived type). + std::string type_name; // Where the section is evaluated, when the reason is about a section, // and why no copy placed before the statement serves it. GpuSectionSite site = GpuSectionSite::Statement; diff --git a/src/libasr/pass/gpu_offload.cpp b/src/libasr/pass/gpu_offload.cpp index ea2a078f48d..facafe4d39d 100644 --- a/src/libasr/pass/gpu_offload.cpp +++ b/src/libasr/pass/gpu_offload.cpp @@ -212,8 +212,10 @@ void GpuOffloadVisitor::visit_OMPRegion(const ASR::OMPRegion_t ®ion) { resolve_enclosing_associates(work, n_dims, enclosing_assoc_map); Vec private_shapes; private_shapes.reserve(al, 4); - privatize_iteration_arrays(region, work, - enclosing_assoc_map, private_shapes); + if (!privatize_iteration_arrays(region, work, + enclosing_assoc_map, private_shapes)) { + return; + } // Detect if the do concurrent is inside a Block scope. If so, // block-local variables need to be collected as kernel parameters diff --git a/src/libasr/pass/gpu_offload_privatize.cpp b/src/libasr/pass/gpu_offload_privatize.cpp index e7c73ec77b5..75e8c253fb5 100644 --- a/src/libasr/pass/gpu_offload_privatize.cpp +++ b/src/libasr/pass/gpu_offload_privatize.cpp @@ -70,6 +70,8 @@ class GpuArrayAccess { return conflicts(acc, path, routine); } + SymbolTable *procedure() const { return routine; } + private: SymbolTable *routine; const PointerTargets &pointers; @@ -181,6 +183,22 @@ class GpuScopedConstructs } }; +// Whether a thread can hold a copy of its own of a variable whose +// elements are of type `elem`. +bool gpu_private_element_type(ASR::ttype_t *elem) { + return ASR::is_a(*elem) || ASR::is_a(*elem) + || ASR::is_a(*elem) + || ASR::is_a(*elem); +} + +// The variables the statements of a loop body name. +std::set gpu_body_names(const ParallelLoopNest &work) { + std::set named; + VarSymbolCollector c(named); + for (size_t i = 0; i < work.n_body; i++) c.visit_stmt(*work.body[i]); + return named; +} + // What a run of statements does with the value an array held when the // run was entered. // Untouched -- never reads it: the array is not accessed, or it is first @@ -202,26 +220,237 @@ class GpuArrayFlowReader { ASR::Array_t *arr; GpuArrayAccess &access; - GpuArrayFlowReader(ASR::symbol_t *sym_, GpuArrayAccess &access_) + GpuArrayFlowReader(ASR::symbol_t *sym_, GpuArrayAccess &access_, + const std::set &host_associated_) : sym(sym_), arr(ASR::down_cast( - ASRUtils::symbol_type(sym_))), access(access_) {} + ASRUtils::symbol_type(sym_))), access(access_), + host_associated(host_associated_) {} // `escaped` is set when a path may leave the run elsewhere than past // its end, by a jump out of one of its statements, wherever that // statement nests it. Such a path skips what the rest of the run // defines. GpuArrayFlow run(ASR::stmt_t **body, size_t n_body, bool &escaped) { + counters.clear(); + elements.clear(); for (size_t i = 0; i < n_body; i++) { Leaves leaves; leaves.visit_stmt(*body[i]); if (leaves.found) escaped = true; GpuArrayFlow f = stmt(body[i]); if (f != GpuArrayFlow::Untouched) return f; + count(body[i]); } return GpuArrayFlow::Untouched; } private: + const std::set &host_associated; + + // What the statements of the run read so far tell: the values of + // integer locals known at this point of it, and the elements of the + // array, by their offset in array element order, it has defined. + // A run that defines every element one by one -- the array + // constructor lowering `k = 1; t(k) = a; k = k + 1; t(k) = b; ...`, + // or `t(1) = a; t(2) = b` -- defines all of it. + std::map counters; + std::set elements; + + // An integer local that only a statement that names it can change. + bool trackable(ASR::symbol_t *s) { + if (s == sym || !ASR::is_a(*s)) return false; + ASR::Variable_t *v = ASR::down_cast(s); + return ASR::is_a(*v->m_type) + && v->m_intent == ASR::intentType::Local + && !v->m_is_volatile && v->m_common_block == nullptr + && !reachable_elsewhere(s, access.procedure()) + && host_associated.count(s) == 0; + } + + bool evaluate(ASR::expr_t *e, int64_t &v) { + if (e == nullptr) return false; + if (constant(e, v)) return true; + switch (e->type) { + case ASR::exprType::Var: { + auto it = counters.find(ASR::down_cast(e)->m_v); + if (it == counters.end()) return false; + v = it->second; + return true; + } + case ASR::exprType::ArrayBound: { + // `lbound(t, d)` of a dimension with constant bounds, as + // the array constructor lowering starts its counter. + ASR::ArrayBound_t *b = ASR::down_cast(e); + int64_t dim = 0, start = 0, length = 0; + if (!ASR::is_a(*b->m_v) || + ASR::down_cast(b->m_v)->m_v != sym || + !constant(b->m_dim, dim) || dim < 1 || + dim > (int64_t)arr->n_dims || + !constant(arr->m_dims[dim - 1].m_start, start) || + !constant(arr->m_dims[dim - 1].m_length, length)) { + return false; + } + v = b->m_bound == ASR::arrayboundType::LBound + ? start : start + length - 1; + return true; + } + case ASR::exprType::Cast: { + ASR::Cast_t *c = ASR::down_cast(e); + return c->m_kind == ASR::cast_kindType::IntegerToInteger + && evaluate(c->m_arg, v); + } + case ASR::exprType::IntegerBinOp: { + ASR::IntegerBinOp_t *b = ASR::down_cast( + e); + int64_t l = 0, r = 0; + if (!evaluate(b->m_left, l) || !evaluate(b->m_right, r)) { + return false; + } + if (b->m_op == ASR::binopType::Add) v = l + r; + else if (b->m_op == ASR::binopType::Sub) v = l - r; + else return false; + return true; + } + default: return false; + } + } + + // Follows the integer locals a statement the run went on past + // assigns. Only two kinds of statement keep what is known: `k = e` + // where `k` is such a local and `e` a value `evaluate` knows, which + // calls nothing; and the definition of an element (`element`), which + // calls no procedure that is not pure, and so changes no local but + // its target. Every other statement -- an assignment to anything + // else (an associate name of a local among them), a call, a loop, + // an input statement -- may change one in ways not followed here, + // and forgets them all. + void count(ASR::stmt_t *s) { + if (ASR::is_a(*s)) { + ASR::Assignment_t *a = ASR::down_cast(s); + if (a->m_overloaded == nullptr && ASR::is_a( + *a->m_target)) { + ASR::symbol_t *t = ASR::down_cast( + a->m_target)->m_v; + int64_t v = 0; + if (trackable(t) && evaluate(a->m_value, v)) { + counters[t] = v; + return; + } + } else if (element(s, nullptr)) { + return; + } + } + counters.clear(); + } + + // Whether `e` may call a procedure that is not pure, which may change + // a local passed to it or reached through a pointer. A pure function + // changes neither its arguments nor anything outside it (F2018 + // 15.7, C1583, C1594). + static bool calls_impure(ASR::expr_t *e) { + struct Calls : public ASR::BaseWalkVisitor { + bool found = false; + void visit_FunctionCall(const ASR::FunctionCall_t &x) { + ASR::symbol_t *f = ASRUtils::symbol_get_past_external( + x.m_name); + if (!ASR::is_a(*f) || + !ASRUtils::get_FunctionType( + ASR::down_cast(f))->m_pure) { + found = true; + } + ASR::BaseWalkVisitor::visit_FunctionCall(x); + } + } calls; + calls.visit_expr(*e); + return calls.found; + } + + // Whether an element of the array, its subscripts values known here, + // is one the run has defined; `offset` is set to its position in + // array element order. + bool known_element(const ASR::ArrayItem_t &item, int64_t &offset, + bool defined) { + if (!ASR::is_a(*item.m_v) || + ASR::down_cast(item.m_v)->m_v != sym || + item.n_args != arr->n_dims) { + return false; + } + int64_t position = 0, stride = 1; + for (size_t d = 0; d < item.n_args; d++) { + const ASR::array_index_t &idx = item.m_args[d]; + int64_t start = 0, length = 0, v = 0; + if (idx.m_left || idx.m_step || + !constant(arr->m_dims[d].m_start, start) || + !constant(arr->m_dims[d].m_length, length) || + !evaluate(idx.m_right, v) || + v < start || v >= start + length) { + return false; + } + position += (v - start) * stride; + stride *= length; + } + offset = position; + return !defined || elements.count(position) > 0; + } + + // Whether `e` reads the array only through elements the run has + // defined, `t(2) + 1.0` after `t(2) = a`. + bool reads_defined(ASR::expr_t *e) { + if (!access.expr(e)) return true; + struct Reads : public ASR::BaseWalkVisitor { + GpuArrayFlowReader &r; + bool ok = true; + explicit Reads(GpuArrayFlowReader &r_) : r(r_) {} + void visit_ArrayItem(const ASR::ArrayItem_t &x) { + int64_t offset = 0; + if (ASR::is_a(*x.m_v) && + ASR::down_cast(x.m_v)->m_v == r.sym) { + ok = ok && r.known_element(x, offset, true); + return; + } + ASR::BaseWalkVisitor::visit_ArrayItem(x); + } + void visit_Var(const ASR::Var_t &x) { + if (x.m_v == r.sym) ok = false; + } + } reads(*this); + reads.visit_expr(*e); + return reads.ok; + } + + // `t(i1, ..., ir) = v`, each subscript a value known here within the + // declared bounds of its dimension, where `v` reads `t` only through + // elements defined before and calls no procedure that is not pure. + // `offset` is set to the element's position in array element order. + bool element(ASR::stmt_t *s, int64_t *offset) { + if (!ASR::is_a(*s)) return false; + ASR::Assignment_t *a = ASR::down_cast(s); + if (a->m_overloaded != nullptr || + !ASR::is_a(*a->m_target) || + !reads_defined(a->m_value)) { + return false; + } + if (calls_impure(a->m_value)) return false; + int64_t position = 0; + if (!known_element(*ASR::down_cast(a->m_target), + position, false)) { + return false; + } + if (offset) *offset = position; + return true; + } + + // The number of elements of the array, when it is a constant. + bool extent(int64_t &n) { + n = 1; + for (size_t d = 0; d < arr->n_dims; d++) { + int64_t length = 0; + if (!constant(arr->m_dims[d].m_length, length)) return false; + n *= length; + } + return true; + } + static bool constant(ASR::expr_t *e, int64_t &v) { return e != nullptr && ASRUtils::extract_value(ASRUtils::expr_value(e), v); @@ -362,8 +591,16 @@ class GpuArrayFlowReader { // early may go on past the statement that holds it without having // defined the array (`exit` of a BLOCK construct). GpuArrayFlow nested(ASR::stmt_t **body, size_t n_body) { + // The list is read on its own; what the run around it knows is + // taken up again after it. + std::map outer_counters; + std::set outer_elements; + std::swap(outer_counters, counters); + std::swap(outer_elements, elements); bool escaped = false; GpuArrayFlow f = run(body, n_body, escaped); + std::swap(outer_counters, counters); + std::swap(outer_elements, elements); return escaped && f == GpuArrayFlow::Defined ? GpuArrayFlow::Untouched : f; } @@ -399,8 +636,12 @@ class GpuArrayFlowReader { if (!access.stmt(s)) return GpuArrayFlow::Untouched; switch (s->type) { case ASR::stmtType::Assignment: { - return defines_whole(s) ? GpuArrayFlow::Defined - : GpuArrayFlow::Read; + if (defines_whole(s)) return GpuArrayFlow::Defined; + int64_t offset = 0, n = 0; + if (!element(s, &offset)) return GpuArrayFlow::Read; + elements.insert(offset); + return extent(n) && (int64_t)elements.size() == n + ? GpuArrayFlow::Defined : GpuArrayFlow::Untouched; } case ASR::stmtType::If: { ASR::If_t *x = ASR::down_cast(s); @@ -425,6 +666,22 @@ class GpuArrayFlowReader { } return nested(blk->m_body, blk->n_body); } + case ASR::stmtType::AssociateBlockCall: { + // The selectors are bound by the leading statements of + // the body, which `access` reads like any other: one that + // names the array is taken to read it. + ASR::symbol_t *b = ASRUtils::symbol_get_past_external( + ASR::down_cast(s)->m_m); + if (!ASR::is_a(*b)) { + return GpuArrayFlow::Read; + } + ASR::AssociateBlock_t *ab = + ASR::down_cast(b); + if (access.declarations(ab->m_symtab)) { + return GpuArrayFlow::Read; + } + return nested(ab->m_body, ab->n_body); + } case ASR::stmtType::DoLoop: { ASR::DoLoop_t *x = ASR::down_cast(s); if (defines_by_loops(x)) return GpuArrayFlow::Defined; @@ -606,9 +863,11 @@ bool read_after_region(GpuArrayFlowReader &reader, // // An array is only made local where that cannot be told apart: every // path through the body that accesses it first defines all of it -- by -// an assignment to the whole array, or by a nest of DO loops over its full -// declared extent -- and no statement that can run after the loop, however -// a jump gets there, may read it before it is defined again. So no +// an assignment to the whole array, by a nest of DO loops over its full +// declared extent, or by assignments to each of its elements in turn, as +// the lowering of an array constructor fills its temporary -- and no +// statement that can run after the loop, however a jump gets there, may +// read it before it is defined again. So no // iteration reads a value it did not define, whether every iteration, // some or none define the array, and nothing after the loop reads what // they defined. It is a local, non-saved variable that no pointer and no @@ -675,13 +934,7 @@ GpuOffloadVisitor::iteration_array_candidates( if (s == proc_scope) break; } - std::set named; - { - VarSymbolCollector c(named); - for (size_t i = 0; i < work.n_body; i++) { - c.visit_stmt(*work.body[i]); - } - } + std::set named = gpu_body_names(work); // What the procedures contained in this one name, which they reach by // host association. @@ -730,13 +983,7 @@ GpuOffloadVisitor::iteration_array_candidates( continue; } ASR::Array_t *arr = ASR::down_cast(v->m_type); - ASR::ttype_t *elem = arr->m_type; - if (!ASR::is_a(*elem) && - !ASR::is_a(*elem) && - !ASR::is_a(*elem) && - !ASR::is_a(*elem)) { - continue; - } + if (!gpu_private_element_type(arr->m_type)) continue; GpuArrayAccess access(sym, proc_scope, pointers, outside); bool named_outside_body = false; for (size_t d = 0; d < work.n_heads(); d++) { @@ -753,7 +1000,7 @@ GpuOffloadVisitor::iteration_array_candidates( } if (named_outside_body) continue; - GpuArrayFlowReader reader(sym, access); + GpuArrayFlowReader reader(sym, access, host_associated); bool escaped = false; if (reader.run(work.body, work.n_body, escaped) == GpuArrayFlow::Read) { @@ -769,15 +1016,104 @@ GpuOffloadVisitor::iteration_array_candidates( return candidates; } +// A variable of LOCAL locality (`local(t)`, the OMPPrivate clause of the +// canonical region) is a construct entity: each iteration has its own, +// undefined on entry, and the variable outside the loop is not affected +// by it (Fortran 2018, 11.1.7.5). It becomes a local of the BLOCK around +// the body, with no analysis of the body. +bool GpuOffloadVisitor::locality_spec_variables( + const ASR::OMPRegion_t ®ion, ParallelLoopNest &work, + const std::map &enclosing_assoc_map, + std::vector &local, GpuDecline &rejected) { + std::set named = gpu_body_names(work); + std::set indices; + for (size_t d = 0; d < work.n_heads(); d++) { + if (work.head(d).m_v && ASR::is_a(*work.head(d).m_v)) { + indices.insert(ASR::down_cast( + work.head(d).m_v)->m_v); + } + } + std::set in_associates; + { + VarSymbolCollector c(in_associates); + for (auto &assoc : enclosing_assoc_map) { + in_associates.insert(assoc.first); + c.visit_expr(*assoc.second); + } + } + bool inlined = gpu_associates_inlined(work.body, work.n_body, true); + for (size_t i = 0; i < region.n_clauses; i++) { + if (!ASR::is_a(*region.m_clauses[i])) continue; + ASR::OMPPrivate_t *clause = ASR::down_cast( + region.m_clauses[i]); + for (size_t k = 0; k < clause->n_vars; k++) { + if (!ASR::is_a(*clause->m_vars[k])) continue; + ASR::symbol_t *sym = ASR::down_cast( + clause->m_vars[k])->m_v; + if (!ASR::is_a(*sym) || !named.count(sym) || + indices.count(sym) || + std::find(local.begin(), local.end(), sym) + != local.end()) { + continue; + } + ASR::Variable_t *v = ASR::down_cast(sym); + ASR::ttype_t *elem = ASRUtils::type_get_past_array(v->m_type); + GpuDeclineReason why = GpuDeclineReason::None; + if (!gpu_private_element_type(elem)) { + why = GpuDeclineReason::LocalityElementType; + } else if (v->n_codims > 0) { + why = GpuDeclineReason::LocalityCoarray; + } else if (in_associates.count(sym)) { + why = GpuDeclineReason::LocalityNamedByAssociate; + } else if (!inlined) { + why = GpuDeclineReason::LocalityAssociateNotInlined; + } + if (why == GpuDeclineReason::None) { + local.push_back(sym); + continue; + } + // A scalar the body assigns is still a local of each thread + // (see visit_OMPRegion); an array would be one buffer that + // every thread shares. + if (ASRUtils::is_array(v->m_type)) { + rejected = GpuDecline(why, v->m_name); + rejected.type_name = ASRUtils::type_to_str_fortran_symbol( + elem, v->m_type_declaration, true); + if (ASR::is_a(*elem) && + !ASR::down_cast(elem) + ->m_is_unlimited_polymorphic) { + rejected.type_name = (ASR::down_cast( + elem)->m_is_cstruct ? "type(" : "class(") + + rejected.type_name + ")"; + } + return false; + } + } + } + return true; +} + // Locality is a correctness decision. Storage is assigned only after // shared lowering has materialized the kernel's arrays. -void GpuOffloadVisitor::privatize_iteration_arrays( +bool GpuOffloadVisitor::privatize_iteration_arrays( const ASR::OMPRegion_t ®ion, ParallelLoopNest &work, const std::map &enclosing_assoc_map, Vec &private_shapes) { - std::vector privatized = - iteration_array_candidates(region, work, enclosing_assoc_map); - if (privatized.empty()) return; + std::vector privatized; + GpuDecline rejected; + if (!locality_spec_variables(region, work, enclosing_assoc_map, + privatized, rejected)) { + report_not_offloaded(region.base.base.loc, rejected); + return false; + } + for (ASR::symbol_t *sym : iteration_array_candidates(region, work, + enclosing_assoc_map)) { + if (std::find(privatized.begin(), privatized.end(), sym) + == privatized.end()) { + privatized.push_back(sym); + } + } + if (privatized.empty()) return true; std::sort(privatized.begin(), privatized.end(), [](ASR::symbol_t *a, ASR::symbol_t *b) { return std::string(ASRUtils::symbol_name(a)) @@ -810,11 +1146,13 @@ void GpuOffloadVisitor::privatize_iteration_arrays( for (ASR::symbol_t *sym : privatized) { ASR::Variable_t *v = ASR::down_cast(sym); ASR::ttype_t *type = ASRUtils::duplicate_type(al, v->m_type); - auto *array = ASR::down_cast(type); ASRUtils::ASRBuilder b(al, v->base.base.loc); ASR::expr_t *source = ASRUtils::EXPR( ASR::make_Var_t(al, v->base.base.loc, sym)); - for (size_t d = 0; d < array->n_dims; d++) { + size_t n_dims = ASR::is_a(*type) + ? ASR::down_cast(type)->n_dims : 0; + for (size_t d = 0; d < n_dims; d++) { + auto *array = ASR::down_cast(type); auto capture = [&](ASR::expr_t *&dimension, ASR::expr_t *value) { int64_t constant_value; if (dimension && ASRUtils::extract_value( @@ -860,6 +1198,7 @@ void GpuOffloadVisitor::privatize_iteration_arrays( body.push_back(al, ASRUtils::STMT(ASR::make_BlockCall_t(al, loc, -1, block_sym))); work.set_body(body.p, body.n); + return true; } } // namespace LCompilers diff --git a/src/libasr/pass/gpu_offload_visitor.h b/src/libasr/pass/gpu_offload_visitor.h index 7c10145bc2f..a2105d4e4dc 100644 --- a/src/libasr/pass/gpu_offload_visitor.h +++ b/src/libasr/pass/gpu_offload_visitor.h @@ -548,15 +548,26 @@ class GpuOffloadVisitor : public ASR::StatementWalkVisitor void resolve_enclosing_associates(ParallelLoopNest &work, size_t n_dims, std::map &enclosing_assoc_map); - // Gives each iteration its own copy of an array of unspecified - // locality that the iteration defines whole before it references it, - // by making it a local of a BLOCK around the body (see - // gpu_offload_privatize.cpp). - void privatize_iteration_arrays(const ASR::OMPRegion_t ®ion, + // Gives each iteration its own copy of a variable of LOCAL + // locality, and of an array of unspecified locality that + // the iteration defines whole before it references it, by making it a + // local of a BLOCK around the body (see gpu_offload_privatize.cpp). + // False when the loop has been reported as one the kernel cannot run. + bool privatize_iteration_arrays(const ASR::OMPRegion_t ®ion, ParallelLoopNest &work, const std::map &enclosing_assoc_map, Vec &private_shapes); + // Appends to `local` the variables of LOCAL locality that the body + // names and a thread can hold a copy of its own of. A scalar it + // cannot is left alone. An array it cannot makes it return false, + // with `rejected` set to the decline that names the array and why; + // the caller reports it, and the loop is not offloaded. + bool locality_spec_variables(const ASR::OMPRegion_t ®ion, + ParallelLoopNest &work, + const std::map &enclosing_assoc_map, + std::vector &local, GpuDecline &rejected); + // The arrays privatize_iteration_arrays may make local. std::vector iteration_array_candidates( const ASR::OMPRegion_t ®ion, ParallelLoopNest &work, diff --git a/src/libasr/pass/subroutine_from_function.cpp b/src/libasr/pass/subroutine_from_function.cpp index 26a0bc5431b..6cf47cc8a18 100644 --- a/src/libasr/pass/subroutine_from_function.cpp +++ b/src/libasr/pass/subroutine_from_function.cpp @@ -683,8 +683,17 @@ public : } void replace_FunctionCall(ASR::FunctionCall_t* x){ + std::vector original_args; + for (size_t i = 0; i < x->n_args; i++) { + original_args.push_back(x->m_args[i].m_value); + } traverse_functionCall_args(x->m_args, x->n_args); - if (x->m_dt) { + ASR::expr_t* dt = x->m_dt; + for (size_t i = 0; i < x->n_args; i++) { + x->m_dt = passed_object_dispatch(x->m_dt, original_args[i], + x->m_args[i].m_value); + } + if (x->m_dt && x->m_dt == dt) { ASR::expr_t** current_expr_copy = current_expr; current_expr = &(x->m_dt); replace_expr(x->m_dt); @@ -1241,13 +1250,20 @@ class ReplaceFunctionCallWithSubroutineCallVisitor: // We skip the generic expression visitor on this statement, so // ensure nested calls inside the function call arguments are still replaced. + std::vector original_args; for (size_t i = 0; i < fc->n_args; i++) { + original_args.push_back(fc->m_args[i].m_value); ASR::expr_t** current_expr_copy = current_expr; current_expr = &fc->m_args[i].m_value; call_replacer(); current_expr = current_expr_copy; } - if (fc->m_dt) { + ASR::expr_t* dt = fc->m_dt; + for (size_t i = 0; i < fc->n_args; i++) { + fc->m_dt = passed_object_dispatch(fc->m_dt, original_args[i], + fc->m_args[i].m_value); + } + if (fc->m_dt && fc->m_dt == dt) { ASR::expr_t** current_expr_copy = current_expr; current_expr = &fc->m_dt; call_replacer(); diff --git a/src/libasr/runtime/lfortran_gpu_cpu.c b/src/libasr/runtime/lfortran_gpu_cpu.c index be4f807c878..65897420fc9 100644 --- a/src/libasr/runtime/lfortran_gpu_cpu.c +++ b/src/libasr/runtime/lfortran_gpu_cpu.c @@ -206,6 +206,8 @@ void lfortran_gpu_launch(lfortran_gpu_ctx* ctx, lfortran_gpu_kernel* k, int grid[3], int block[3]) { if (!ctx || !k) return; + // As in the CUDA runtime, a launch of no threads runs nothing. + if (lfortran_gpu_launch_is_empty(grid, block)) return; // Same argument array the CUDA runtime hands to cudaLaunchKernel: every // entry points at the argument value. diff --git a/src/libasr/runtime/lfortran_gpu_cuda.cu b/src/libasr/runtime/lfortran_gpu_cuda.cu index 62125199ed5..c0ede8e6f93 100644 --- a/src/libasr/runtime/lfortran_gpu_cuda.cu +++ b/src/libasr/runtime/lfortran_gpu_cuda.cu @@ -33,6 +33,11 @@ default stream ordering every copy and launch: is a dirty range, the kernel reads the resident memory instead. * A range that overlaps a dirty one without being the same range makes the runtime sync first. +* A scratch buffer, which only the device holds, is the memory its argument + slot keeps as well. What a launch leaves there is dead once it ends (a part + the host reads back is read before the next launch is made), and the + stream runs the launches one after another, so every launch of the kernel + uses the same memory, however many of them are still pending. * Memory a launch may still use is freed only at the next sync. */ @@ -202,7 +207,8 @@ static void* dirty_resident(void *host, size_t size) { return entries[i].device; } -// The memory argument `idx` of a kernel keeps for what it only reads. +// The memory argument `idx` of a kernel keeps for what it only reads, or +// for its scratch buffer. static void* slot_buffer(slot_cache *cache, int idx, size_t size) { if (cache->buffers[idx] && cache->capacities[idx] >= size) { return cache->buffers[idx]; @@ -280,7 +286,6 @@ lfortran_gpu_kernel* lfortran_gpu_load_kernel( void lfortran_gpu_release_kernel(lfortran_gpu_kernel* k) { if (!k) return; for (int i = 0; i < k->n_args; i++) { - if (k->kind[i] == ARG_SCRATCH) free_later(k->buffer_device_ptrs[i]); if (k->kind[i] == ARG_SCALAR && k->scalar_args[i].data) { free(k->scalar_args[i].data); } @@ -305,16 +310,17 @@ void lfortran_gpu_set_scratch_arg(lfortran_gpu_kernel* k, int idx, if (!k || idx >= MAX_ARGS) return; k->buffer_host_ptrs[idx] = NULL; k->buffer_sizes[idx] = size; + k->buffer_device_ptrs[idx] = NULL; k->kind[idx] = ARG_SCRATCH; if (idx >= k->n_args) k->n_args = idx + 1; - k->buffer_device_ptrs[idx] = size > 0 ? device_alloc(size) : NULL; } void lfortran_gpu_read_scratch_arg(lfortran_gpu_kernel* k, int idx, void* dst, size_t size) { if (!k || idx >= MAX_ARGS || size == 0) return; - if (k->kind[idx] != ARG_SCRATCH || size > k->buffer_sizes[idx]) { + if (k->kind[idx] != ARG_SCRATCH || !k->buffer_device_ptrs[idx] + || size > k->buffer_sizes[idx]) { fprintf(stderr, "lfortran_gpu_read_scratch_arg: no scratch buffer " "%d of %zu bytes\n", idx, size); exit(1); @@ -342,6 +348,10 @@ void lfortran_gpu_launch(lfortran_gpu_ctx* ctx, lfortran_gpu_kernel* k, int grid[3], int block[3]) { if (!ctx || !k) return; + // A launch of no threads (an empty iteration space) runs nothing, and + // CUDA rejects a grid or a block with a zero extent: there is nothing + // to copy in or launch, and the host and device copies stay as they are. + if (lfortran_gpu_launch_is_empty(grid, block)) return; for (int i = 0; i < k->n_args; i++) { if (k->kind[i] == ARG_BUFFER @@ -375,6 +385,11 @@ void lfortran_gpu_launch(lfortran_gpu_ctx* ctx, lfortran_gpu_kernel* k, } k->buffer_device_ptrs[i] = d_ptr; } + for (int i = 0; i < k->n_args; i++) { + if (k->kind[i] != ARG_SCRATCH) continue; + k->buffer_device_ptrs[i] = k->buffer_sizes[i] == 0 ? NULL + : slot_buffer(k->cache, i, k->buffer_sizes[i]); + } // Build the kernel argument array for cudaLaunchKernel: a device // pointer for a buffer, the value for a scalar. diff --git a/src/libasr/runtime/lfortran_gpu_runtime.h b/src/libasr/runtime/lfortran_gpu_runtime.h index b91e8c60a3f..191b120acf3 100644 --- a/src/libasr/runtime/lfortran_gpu_runtime.h +++ b/src/libasr/runtime/lfortran_gpu_runtime.h @@ -26,6 +26,17 @@ static inline void lfortran_gpu_copy_kernel_name(char *dest, const char *name, dest[name_len] = '\0'; } +// Whether a launch has no threads: a grid or block extent that is not +// positive, as an empty iteration space gives. Such a launch runs nothing. +static inline int lfortran_gpu_launch_is_empty(const int grid[3], + const int block[3]) +{ + for (int i = 0; i < 3; i++) { + if (grid[i] <= 0 || block[i] <= 0) return 1; + } + return 0; +} + // The size in bytes of the device heap of a launch that allocates on the // device: the value of the environment variable LFORTRAN_GPU_HEAP_SIZE, a // number with an optional K, M or G suffix (powers of 1024), or 256 MiB when @@ -122,7 +133,8 @@ void lfortran_gpu_set_buffer_arg(lfortran_gpu_kernel* k, int idx, void lfortran_gpu_set_scalar_arg(lfortran_gpu_kernel* k, int idx, const void* val, size_t size); // A buffer of `size` bytes only the device holds: nothing is copied in or -// back, and the kernel object owns it until it is released. +// back. What the launch leaves in it lasts until the next launch of the +// kernel; the runtime may keep the memory for later launches. void lfortran_gpu_set_scratch_arg(lfortran_gpu_kernel* k, int idx, size_t size); // Copies the leading `size` bytes of the scratch buffer `idx` into `dst`, diff --git a/src/libasr/utils.h b/src/libasr/utils.h index ce38ccfc693..37b933588b3 100644 --- a/src/libasr/utils.h +++ b/src/libasr/utils.h @@ -135,6 +135,9 @@ struct CompilerOptions { bool gpu_cpu_emulation = false; // Toolchain driver used to compile and link GPU device code. std::string device_compiler = "nvcc"; + // GPU architecture the device code is compiled for, such as sm_120. + // Empty means the GPUs of the machine that compiles. + std::string gpu_arch = ""; std::string openmp_lib_dir = ""; bool lookup_name = false; bool rename_symbol = false; diff --git a/src/tests/test_cuda_link_helpers.cpp b/src/tests/test_cuda_link_helpers.cpp new file mode 100644 index 00000000000..8026cebede9 --- /dev/null +++ b/src/tests/test_cuda_link_helpers.cpp @@ -0,0 +1,102 @@ +#include + +#include "../bin/cuda_link_helpers.h" +#include "test_cuda_link_helpers_fixture.hpp" + +#include +#include +#include +#include +#include +#include +#include + +namespace fs = std::filesystem; + +namespace { + +static void write_file(const fs::path &path, const std::string &text) +{ + std::ofstream out(path); + if (!out.is_open()) { + throw std::runtime_error("failed to open " + path.string()); + } + out << text; +} + +struct OwnedDirectory { + fs::path path; + + explicit OwnedDirectory(const fs::path &root, const std::string &prefix) + { + fs::create_directories(root); + for (int i = 0; i < 32; ++i) { + fs::path candidate = root / (prefix + "_" + LCompilers::get_unique_ID()); + std::error_code ec; + if (fs::create_directory(candidate, ec)) { + path = candidate; + return; + } + } + throw std::runtime_error("failed to create unique directory under " + root.string()); + } + + ~OwnedDirectory() + { + std::error_code ec; + fs::remove_all(path, ec); + } +}; + +} // namespace + +TEST_CASE("CUDA library resolution prefers shared libraries unless static is effective") +{ + OwnedDirectory workdir(fs::path(cuda_link_helpers_fixture::plain_archive).parent_path(), + "cuda_link_helper_resolve"); + + const fs::path so = workdir.path / "libformal.so"; + const fs::path archive = workdir.path / "libformal.a"; + write_file(so, "shared"); + write_file(archive, "archive"); + + std::filesystem::path resolved; + bool is_static_archive = false; + + REQUIRE(resolve_linker_library("formal", {workdir.path.string()}, + LCompilers::Platform::Linux, false, resolved, is_static_archive)); + CHECK(resolved == so); + CHECK_FALSE(is_static_archive); + + REQUIRE(resolve_linker_library("formal", {workdir.path.string()}, + LCompilers::Platform::Linux, true, resolved, is_static_archive)); + CHECK(resolved == archive); + CHECK(is_static_archive); +} + +#ifdef HAVE_LFORTRAN_LLVM +TEST_CASE("Metadata-free archives ignore unrelated member sidecars") { + OwnedDirectory workdir(fs::path(cuda_link_helpers_fixture::plain_archive).parent_path(), + "cuda_link_helper_archive"); + + const fs::path archive = workdir.path / "libplain.a"; + { + std::error_code ec; + fs::copy_file(cuda_link_helpers_fixture::plain_archive, archive, ec); + if (ec) { + throw std::runtime_error("failed to copy fixture archive to " + archive.string() + + ": " + ec.message()); + } + } + + const fs::path ignored_sidecar = + workdir.path / (std::string(cuda_link_helpers_fixture::plain_member) + ".cuda.cu"); + write_file(ignored_sidecar, "#error unrelated member sidecar must be ignored\n"); + + std::set seen_sidecars; + std::vector cuda_sources; + REQUIRE(append_cuda_source_from_library("plain", {workdir.path.string()}, + LCompilers::Platform::Linux, false, seen_sidecars, cuda_sources)); + CHECK(cuda_sources.empty()); +} +#endif diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_01-0428e9e.json b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_01-0428e9e.json index 7fc75a47c3e..d79aca8ca00 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_01-0428e9e.json +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_01-0428e9e.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_kernel_source_01-0428e9e.stdout", - "stdout_hash": "9e5baeb341e1fccb5d6c5a731e1de6bd35c42b09f31690af45dcadc7", + "stdout_hash": "20675d89e913b63d1a3a9a03bd2c01ec5a310ca40aac399e699f7fba", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_01-0428e9e.stdout b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_01-0428e9e.stdout index 38510ed2a99..60b1b00765b 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_01-0428e9e.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_01-0428e9e.stdout @@ -14,7 +14,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __loop_end_0 = __scalar_args.__loop_end_0; int __flat_idx; int i; - const int n = 1000; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_02-50a3dd7.json b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_02-50a3dd7.json index fe92f3af591..dfd01da1324 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_02-50a3dd7.json +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_02-50a3dd7.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_kernel_source_02-50a3dd7.stdout", - "stdout_hash": "e3a7573f396bf38e2650fdb26801a84b4d79fe2898a79e03ac52c8f0", + "stdout_hash": "51176f44c2d293be2b3fcd815c7cc2eb428fa2686e00a903e34afe82", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_02-50a3dd7.stdout b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_02-50a3dd7.stdout index 3ab966b354e..5277b5e3eea 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_02-50a3dd7.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_02-50a3dd7.stdout @@ -13,7 +13,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __flat_idx; const float a = 2.50000000000000000e+00f; int i; - const int n = 12; const int tbl[3] = {7, 8, 9}; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_03-049e8d1.json b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_03-049e8d1.json index d5d83a59fc6..83915ebd8aa 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_03-049e8d1.json +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_03-049e8d1.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_kernel_source_03-049e8d1.stdout", - "stdout_hash": "d419f06f3641a658693363b54728f2fbca9738ca550cfb763cb07c86", + "stdout_hash": "cb4701ab1a34a491ad67250dd07f87b1fc252559dafa7a9596b73bf1", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_03-049e8d1.stdout b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_03-049e8d1.stdout index d2ebb2095b3..81f15c8e1f1 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_03-049e8d1.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_03-049e8d1.stdout @@ -18,7 +18,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( const float cs[5] = {1.00000000e+00, 5.00000000e-01, 2.50000000e-01, 1.25000000e-01, 6.25000000e-02}; int i; int j; - const int n = 16; const int nc = 5; float twox; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_04-6974c93.json b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_04-6974c93.json index 9c959aec123..1225624821e 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_04-6974c93.json +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_04-6974c93.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_kernel_source_04-6974c93.stdout", - "stdout_hash": "b39a591b178134562b1f23b25867cdd7060f64261f4b981550fcbe57", + "stdout_hash": "2bf25ac26a093e976c44b9794270c89e3f91df4e25d442b3036939ee", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_04-6974c93.stdout b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_04-6974c93.stdout index f0698714ed2..50213a4808e 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_04-6974c93.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_04-6974c93.stdout @@ -12,7 +12,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __loop_end_0 = __scalar_args.__loop_end_0; int __flat_idx; int i; - const int n = 8; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_05-7a49d7a.json b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_05-7a49d7a.json index f41476fd2e4..6f25c8dccca 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_05-7a49d7a.json +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_05-7a49d7a.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_kernel_source_05-7a49d7a.stdout", - "stdout_hash": "3410351a4e1150685a5597cde8f8df42c57a9735e4d0d8cbdef13a8f", + "stdout_hash": "78ef015b7356a4b6289f4d24fefc71486f5eb9f712e68ab8bd717edb", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_05-7a49d7a.stdout b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_05-7a49d7a.stdout index e99005a5fcc..49bd4fc0288 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_05-7a49d7a.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_05-7a49d7a.stdout @@ -12,7 +12,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __loop_end_0 = __scalar_args.__loop_end_0; int __flat_idx; int i; - const int n = 8; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_06-e2e24ed.json b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_06-e2e24ed.json index 62d6806ffd7..59fdd403a04 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_06-e2e24ed.json +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_06-e2e24ed.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_kernel_source_06-e2e24ed.stdout", - "stdout_hash": "ae1f7381390616b838db8e5095f82f91ceb411dd735dd070bd10c43a", + "stdout_hash": "8d94698b68e709f5913ca60463123f5079a12570ac4882ee931513be", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_06-e2e24ed.stdout b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_06-e2e24ed.stdout index a455747317a..fa9419d70c8 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_06-e2e24ed.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_06-e2e24ed.stdout @@ -15,8 +15,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __flat_idx; int i; int j; - const int m = 4; - const int nc = 5; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= ((((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)) * (((__loop_end_1 >= 1)) ? (((__loop_end_1 - 1) + 1)) : (0))))) { return; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_07-85c87ca.json b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_07-85c87ca.json index 0a878c86f17..6f7496075fd 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_07-85c87ca.json +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_07-85c87ca.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_kernel_source_07-85c87ca.stdout", - "stdout_hash": "b668d8afad59d24f39d3b5a2cd680cd26741b87d43df85f394c46c05", + "stdout_hash": "a16607ee7b4980710ec6f58d65b86c4de1147b5510dcc6d270071a9a", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_07-85c87ca.stdout b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_07-85c87ca.stdout index d2210c799f0..03b7f3c9b44 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_07-85c87ca.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_07-85c87ca.stdout @@ -13,7 +13,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __flat_idx; const double c = 2.82094791773878140e-01; int i; - const int n = 8; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_08-7107bec.json b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_08-7107bec.json index 2b34a3a75d5..f4f3ff0e3b4 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_08-7107bec.json +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_08-7107bec.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_kernel_source_08-7107bec.stdout", - "stdout_hash": "d50834fb279d7ecb6d4fe078729bfc6dd9b18ec6fc657f2f1d794885", + "stdout_hash": "72cea0b9caf978c64d13573b7e78db7cfad73c48eb308ef4a35ffce4", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_08-7107bec.stdout b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_08-7107bec.stdout index c12c26cf964..9efae7ea169 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_08-7107bec.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_08-7107bec.stdout @@ -32,7 +32,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int j; int k; const int m = 10000; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } @@ -96,7 +95,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_1( int j; int k; const int m = 10000; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } @@ -145,7 +143,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_2( int j; int k; const int m = 10000; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } @@ -198,7 +195,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_3( int j; int k; const int m = 10000; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_09-d292d10.json b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_09-d292d10.json index a0d586db72d..dac6f5af063 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_09-d292d10.json +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_09-d292d10.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_kernel_source_09-d292d10.stdout", - "stdout_hash": "8c0bfa88e57643432ca7b9570301b78a368ee82dd72ee601f9645d9a", + "stdout_hash": "806cc4001d0860a73e8652009c4616c07d2a7ae8d89818a6e84204d4", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_09-d292d10.stdout b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_09-d292d10.stdout index 1da87099fcc..75476d1a4e9 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_09-d292d10.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_09-d292d10.stdout @@ -22,7 +22,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __flat_idx; int j; int k; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } @@ -79,7 +78,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_1( int __flat_idx; int j; int k; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } @@ -133,7 +131,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_2( aggregate __gpu_struct_argument; int j; int k; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } @@ -173,7 +170,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_3( int __flat_idx; int j; int k; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_14-ae38410.json b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_14-ae38410.json new file mode 100644 index 00000000000..6c880404d7a --- /dev/null +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_14-ae38410.json @@ -0,0 +1,13 @@ +{ + "basename": "gpu_cuda_kernel-gpu_kernel_source_14-ae38410", + "cmd": "lfortran --no-color --gpu=cuda --show-gpu-kernel-source {infile}", + "infile": "tests/../integration_tests/gpu_kernel_source_14.f90", + "infile_hash": "57ad8288c319097f019dbae086cd1dfa65b028269532a66e5a61edeb", + "outfile": null, + "outfile_hash": null, + "stdout": "gpu_cuda_kernel-gpu_kernel_source_14-ae38410.stdout", + "stdout_hash": "92be949a202b305a6a23ea3682152c9dc840e562924b7dfb40d843c8", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_14-ae38410.stdout b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_14-ae38410.stdout new file mode 100644 index 00000000000..c793d6a1232 --- /dev/null +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_14-ae38410.stdout @@ -0,0 +1,106 @@ +#include + +struct __ScalarArgs___lfortran_gpu_kernel_0 { + int __loop_end_0; +}; + +extern "C" __global__ void __lfortran_gpu_kernel_0( + float* g, + float* x, + __ScalarArgs___lfortran_gpu_kernel_0 __scalar_args) +{ + int __loop_end_0 = __scalar_args.__loop_end_0; + int __flat_idx; + int __gpu_elem_i; + int __gpu_sec_i; + int j; + const int n = 8; + if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { + return; + } + __flat_idx = ((blockIdx.x * blockDim.x) + threadIdx.x); + j = (__flat_idx + 1); + { + float t[4]; + { + int __1__libasr_index_; + int __do_loop_end; + float __libasr__created__var__0__array_constructor_[4]; + float e; + __1__libasr_index_ = 1; + __libasr__created__var__0__array_constructor_[((int)(__1__libasr_index_) - (1))] = x[((int)(j) - (1))]; + __1__libasr_index_ = (__1__libasr_index_ + 1); + __libasr__created__var__0__array_constructor_[((int)(__1__libasr_index_) - (1))] = ( 1.00000000000000000e+01f * x[((int)(j) - (1))]); + __1__libasr_index_ = (__1__libasr_index_ + 1); + __libasr__created__var__0__array_constructor_[((int)(__1__libasr_index_) - (1))] = (( 1.00000000000000000e+01f * x[((int)(j) - (1))]) + 1.00000000000000000e+00f); + __1__libasr_index_ = (__1__libasr_index_ + 1); + __libasr__created__var__0__array_constructor_[((int)(__1__libasr_index_) - (1))] = (( 1.00000000000000000e+01f * x[((int)(j) - (1))]) + 2.00000000000000000e+00f); + __1__libasr_index_ = (__1__libasr_index_ + 1); + __gpu_elem_i = (1 - 1); + while (((__gpu_elem_i + 1) <= 4)) { + __gpu_elem_i = (__gpu_elem_i + 1); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + } + __do_loop_end = ((((int)4) + ((int)1)) - 1); + __gpu_sec_i = (1 - 1); + while (((__gpu_sec_i + 1) <= __do_loop_end)) { + __gpu_sec_i = (__gpu_sec_i + 1); + g[((int)(__gpu_sec_i) - (1)) + (4 * ((int)(j) - (1)))] = t[((int)(__gpu_sec_i) - (1))]; + } + } + } +} + +struct __ScalarArgs___lfortran_gpu_kernel_1 { + int __loop_end_0; +}; + +extern "C" __global__ void __lfortran_gpu_kernel_1( + float* g, + float* x, + __ScalarArgs___lfortran_gpu_kernel_1 __scalar_args) +{ + int __loop_end_0 = __scalar_args.__loop_end_0; + int __1__libasr_index_; + int __flat_idx; + int __gpu_elem_i1; + int __gpu_sec_i1; + int j; + const int n = 8; + if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { + return; + } + __flat_idx = ((blockIdx.x * blockDim.x) + threadIdx.x); + j = (__flat_idx + 1); + { + int __do_loop_end; + float __libasr__created__var__1__array_constructor_[4]; + float t[4]; + float u[4]; + __1__libasr_index_ = 1; + __libasr__created__var__1__array_constructor_[((int)(__1__libasr_index_) - (1))] = x[((int)(j) - (1))]; + __1__libasr_index_ = (__1__libasr_index_ + 1); + __libasr__created__var__1__array_constructor_[((int)(__1__libasr_index_) - (1))] = ( 2.00000000000000000e+00f * x[((int)(j) - (1))]); + __1__libasr_index_ = (__1__libasr_index_ + 1); + __libasr__created__var__1__array_constructor_[((int)(__1__libasr_index_) - (1))] = ( 3.00000000000000000e+00f * x[((int)(j) - (1))]); + __1__libasr_index_ = (__1__libasr_index_ + 1); + __libasr__created__var__1__array_constructor_[((int)(__1__libasr_index_) - (1))] = ( 4.00000000000000000e+00f * x[((int)(j) - (1))]); + __1__libasr_index_ = (__1__libasr_index_ + 1); + __gpu_elem_i1 = (1 - 1); + while (((__gpu_elem_i1 + 1) <= 4)) { + __gpu_elem_i1 = (__gpu_elem_i1 + 1); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + } + u[((int)(1) - (1))] = t[((int)(4) - (1))]; + u[((int)(2) - (1))] = t[((int)(3) - (1))]; + u[((int)(3) - (1))] = t[((int)(2) - (1))]; + u[((int)(4) - (1))] = t[((int)(1) - (1))]; + __do_loop_end = ((((int)4) + ((int)1)) - 1); + __gpu_sec_i1 = (1 - 1); + while (((__gpu_sec_i1 + 1) <= __do_loop_end)) { + __gpu_sec_i1 = (__gpu_sec_i1 + 1); + g[((int)(__gpu_sec_i1) - (1)) + (4 * ((int)(j) - (1)))] = u[((int)(__gpu_sec_i1) - (1))]; + } + } +} + diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_15-6a73706.json b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_15-6a73706.json new file mode 100644 index 00000000000..a396530d50d --- /dev/null +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_15-6a73706.json @@ -0,0 +1,13 @@ +{ + "basename": "gpu_cuda_kernel-gpu_kernel_source_15-6a73706", + "cmd": "lfortran --no-color --gpu=cuda --show-gpu-kernel-source {infile}", + "infile": "tests/../integration_tests/gpu_kernel_source_15.f90", + "infile_hash": "b548262f1790e25efae0005dfec351f092d5bd7ec7fc20b287feb76d", + "outfile": null, + "outfile_hash": null, + "stdout": "gpu_cuda_kernel-gpu_kernel_source_15-6a73706.stdout", + "stdout_hash": "18f28f02a5808826efe5328a73e05ac8d00dd72e780ffad8b4992905", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_15-6a73706.stdout b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_15-6a73706.stdout new file mode 100644 index 00000000000..5f4cae90c65 --- /dev/null +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_15-6a73706.stdout @@ -0,0 +1,49 @@ +#include + +__device__ inline float twice_gpu_11(float v) { + float twice; + twice = (((float)2) * v); + return twice; +} + +struct __ScalarArgs___lfortran_gpu_kernel_0 { + float a; + int __dim_x_0; + int __lb_x_0; + int __dim_y_0; + int __lb_y_0; + int __dim_z_0; + int __lb_z_0; + int __dim_z_1; + int __lb_z_1; + int __loop_end_0; +}; + +extern "C" __global__ void __lfortran_gpu_kernel_0( + float* x, + float* y, + float* z, + __ScalarArgs___lfortran_gpu_kernel_0 __scalar_args) +{ + float a = __scalar_args.a; + int __lb_x_0 = __scalar_args.__lb_x_0; + int __lb_y_0 = __scalar_args.__lb_y_0; + int __dim_z_0 = __scalar_args.__dim_z_0; + int __lb_z_0 = __scalar_args.__lb_z_0; + int __lb_z_1 = __scalar_args.__lb_z_1; + int __loop_end_0 = __scalar_args.__loop_end_0; + int __flat_idx; + int i; + if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { + return; + } + __flat_idx = ((blockIdx.x * blockDim.x) + threadIdx.x); + i = (__flat_idx + 1); + { + float t; + t = (a * x[((int)(i) - (__lb_x_0))]); + y[((int)(i) - (__lb_y_0))] = (t + y[((int)(i) - (__lb_y_0))]); + } + z[((int)(i) - (__lb_z_0)) + (__dim_z_0 * ((int)(2) - (__lb_z_1)))] = twice_gpu_11(y[((int)(i) - (__lb_y_0))]); +} + diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_16-ce4a711.json b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_16-ce4a711.json new file mode 100644 index 00000000000..f1e22ea1efc --- /dev/null +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_16-ce4a711.json @@ -0,0 +1,13 @@ +{ + "basename": "gpu_cuda_kernel-gpu_kernel_source_16-ce4a711", + "cmd": "lfortran --no-color --gpu=cuda --show-gpu-kernel-source {infile}", + "infile": "tests/../integration_tests/gpu_kernel_source_16.f90", + "infile_hash": "aede8dcc14c79ba45cbbb2144a62c69e47d34bb8e86f294a824b2a02", + "outfile": null, + "outfile_hash": null, + "stdout": "gpu_cuda_kernel-gpu_kernel_source_16-ce4a711.stdout", + "stdout_hash": "cc2f846efe1474b0f0ffadf3ae0cf2796d79d6026c0dbc9d570faa89", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/gpu_cuda_kernel-gpu_kernel_source_16-ce4a711.stdout b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_16-ce4a711.stdout new file mode 100644 index 00000000000..bd7edd77c93 --- /dev/null +++ b/tests/reference/gpu_cuda_kernel-gpu_kernel_source_16-ce4a711.stdout @@ -0,0 +1,49 @@ +#include + +extern "C" __global__ void __lfortran_gpu_kernel_0( + float* g, + float* t, + float* x) +{ + int __flat_idx; + int __gpu_bc_i; + int j; + if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= 1)) { + return; + } + __flat_idx = ((blockIdx.x * blockDim.x) + threadIdx.x); + j = (__flat_idx + 1); + __gpu_bc_i = (1 - 1); + while (((__gpu_bc_i + 1) <= 2)) { + __gpu_bc_i = (__gpu_bc_i + 1); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01f); + } + g[((int)(j) - (1))] = t[((int)(1) - (1))]; +} + +struct __ScalarArgs___lfortran_gpu_kernel_1 { + int __loop_end_0; +}; + +extern "C" __global__ void __lfortran_gpu_kernel_1( + float* g, + float* u, + float* x, + __ScalarArgs___lfortran_gpu_kernel_1 __scalar_args) +{ + int __loop_end_0 = __scalar_args.__loop_end_0; + int __flat_idx; + int j; + int k; + const int n = 8; + if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { + return; + } + __flat_idx = ((blockIdx.x * blockDim.x) + threadIdx.x); + j = (__flat_idx + 1); + k = 1; + u[((int)(k) - (1))] = 1.00000000000000000e+00f; + u[((int)(((k + 1) - 1)) - (1))] = 1.00000000000000000e+00f; + g[((int)(j) - (1))] = ((u[((int)(1) - (1))] + u[((int)(2) - (1))]) + x[((int)(j) - (1))]); +} + diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_167-53cda6a.json b/tests/reference/gpu_cuda_kernel-gpu_metal_167-53cda6a.json index 4071c2d3922..3b63bdc062c 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_167-53cda6a.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_167-53cda6a.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_167-53cda6a.stdout", - "stdout_hash": "2682b9a1aecf8937c6e1796fea26c5f2ee23f30fad8702783f402390", + "stdout_hash": "88fcca9a21c41a30db16054c4c2317cd5cb4da31c4d1d3fb086388d6", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_167-53cda6a.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_167-53cda6a.stdout index 37887715a08..244d5615128 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_167-53cda6a.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_167-53cda6a.stdout @@ -51,12 +51,8 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( __ScalarArgs___lfortran_gpu_kernel_0 __scalar_args, float* __workspace_5) { - int nb = __scalar_args.nb; int __dim_a_0 = __scalar_args.__dim_a_0; - int __lb_a_0 = __scalar_args.__lb_a_0; int __dim_a_1 = __scalar_args.__dim_a_1; - int __lb_a_1 = __scalar_args.__lb_a_1; - int __dim_d_0 = __scalar_args.__dim_d_0; int __lb_d_0 = __scalar_args.__lb_d_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_176-d54ae7a.json b/tests/reference/gpu_cuda_kernel-gpu_metal_176-d54ae7a.json index 2bcfe3cddcf..08738344ff5 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_176-d54ae7a.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_176-d54ae7a.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_176-d54ae7a.stdout", - "stdout_hash": "6d28ce09241743b6b6c9832898851d93ee81bed4d4cf705513621a48", + "stdout_hash": "e298f23511484cb548f5d69ceec5cce037fbcbf4a3d9baf27ecb09fb", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_176-d54ae7a.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_176-d54ae7a.stdout index 14785f67bcb..958e0be1321 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_176-d54ae7a.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_176-d54ae7a.stdout @@ -22,7 +22,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( float* __workspace_6, float* __workspace_7) { - int mbs = __scalar_args.mbs; int n = __scalar_args.n; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_177-e8939af.json b/tests/reference/gpu_cuda_kernel-gpu_metal_177-e8939af.json index a430a346980..74c42a5d51f 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_177-e8939af.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_177-e8939af.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_177-e8939af.stdout", - "stdout_hash": "49623cd55e0e32e9e5459fe55e2f0c6617ec2761c86c8c9326457fc6", + "stdout_hash": "9a0bb5cc42eb8d4b2764cc2cb156258f88a2bf1d588062cf1251750a", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_177-e8939af.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_177-e8939af.stdout index 28f19f5ea7f..d2efb5d9dcc 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_177-e8939af.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_177-e8939af.stdout @@ -43,7 +43,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( float* __workspace_7) { int n = __scalar_args.n; - int __dim_arr_0 = __scalar_args.__dim_arr_0; int __lb_arr_0 = __scalar_args.__lb_arr_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_213-3f07f96.json b/tests/reference/gpu_cuda_kernel-gpu_metal_213-3f07f96.json index ae6eb5447a9..c13025f90ba 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_213-3f07f96.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_213-3f07f96.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_213-3f07f96.stdout", - "stdout_hash": "519b328f21fcf6deb10e056a686f31a0f2de31481b42c3347ebb3e2f", + "stdout_hash": "f5d0139122c2cae533a473cb36ef5ab79456be04dc1c113b6e2bd191", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_213-3f07f96.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_213-3f07f96.stdout index ecae1eacac8..ec4650db65b 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_213-3f07f96.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_213-3f07f96.stdout @@ -37,7 +37,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_1( double* d, __ScalarArgs___lfortran_gpu_kernel_1 __scalar_args) { - int __dim_d_0 = __scalar_args.__dim_d_0; int __lb_d_0 = __scalar_args.__lb_d_0; int __flat_idx; int i; @@ -61,9 +60,7 @@ extern "C" __global__ void __lfortran_gpu_kernel_2( double* y, __ScalarArgs___lfortran_gpu_kernel_2 __scalar_args) { - int __dim_x_0 = __scalar_args.__dim_x_0; int __lb_x_0 = __scalar_args.__lb_x_0; - int __dim_y_0 = __scalar_args.__dim_y_0; int __lb_y_0 = __scalar_args.__lb_y_0; int __flat_idx; int i; @@ -88,7 +85,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_3( { int __dim_m_0 = __scalar_args.__dim_m_0; int __lb_m_0 = __scalar_args.__lb_m_0; - int __dim_m_1 = __scalar_args.__dim_m_1; int __lb_m_1 = __scalar_args.__lb_m_1; int __flat_idx; int i; @@ -117,9 +113,7 @@ extern "C" __global__ void __lfortran_gpu_kernel_4( long* k, __ScalarArgs___lfortran_gpu_kernel_4 __scalar_args) { - int __dim_d_0 = __scalar_args.__dim_d_0; int __lb_d_0 = __scalar_args.__lb_d_0; - int __dim_k_0 = __scalar_args.__dim_k_0; int __lb_k_0 = __scalar_args.__lb_k_0; int __flat_idx; int i; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_265-880d0b8.json b/tests/reference/gpu_cuda_kernel-gpu_metal_265-880d0b8.json index d9875a7c607..b55ef16b7d4 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_265-880d0b8.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_265-880d0b8.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_265-880d0b8.stdout", - "stdout_hash": "399791c8b5c7b13ad1061de72b312fedfb8770d043c1c8e701f1274e", + "stdout_hash": "445eded1a28c11228bf208591ef24145cfdb52e6dc2aa106bc67e766", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_265-880d0b8.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_265-880d0b8.stdout index 30340bec84d..ce82884c624 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_265-880d0b8.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_265-880d0b8.stdout @@ -13,9 +13,7 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( float* b, __ScalarArgs___lfortran_gpu_kernel_0 __scalar_args) { - int __dim_a_0 = __scalar_args.__dim_a_0; int __lb_a_0 = __scalar_args.__lb_a_0; - int __dim_b_0 = __scalar_args.__dim_b_0; int __lb_b_0 = __scalar_args.__lb_b_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __flat_idx; @@ -57,18 +55,15 @@ extern "C" __global__ void __lfortran_gpu_kernel_1( float* __workspace_5, float* __workspace_6) { - int n = __scalar_args.n; int __dim_op_0 = __scalar_args.__dim_op_0; int __lb_op_0 = __scalar_args.__lb_op_0; int __dim_op_1 = __scalar_args.__dim_op_1; int __lb_op_1 = __scalar_args.__lb_op_1; int __dim_out_0 = __scalar_args.__dim_out_0; int __lb_out_0 = __scalar_args.__lb_out_0; - int __dim_out_1 = __scalar_args.__dim_out_1; int __lb_out_1 = __scalar_args.__lb_out_1; int __dim_v_0 = __scalar_args.__dim_v_0; int __lb_v_0 = __scalar_args.__lb_v_0; - int __dim_v_1 = __scalar_args.__dim_v_1; int __lb_v_1 = __scalar_args.__lb_v_1; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; @@ -159,9 +154,7 @@ extern "C" __global__ void __lfortran_gpu_kernel_2( float* __workspace_3) { int n = __scalar_args.n; - int __dim_a_0 = __scalar_args.__dim_a_0; int __lb_a_0 = __scalar_args.__lb_a_0; - int __dim_b_0 = __scalar_args.__dim_b_0; int __lb_b_0 = __scalar_args.__lb_b_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_277-2406dc4.json b/tests/reference/gpu_cuda_kernel-gpu_metal_277-2406dc4.json index 4ced0d199fe..c01c6b481da 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_277-2406dc4.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_277-2406dc4.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_277-2406dc4.stdout", - "stdout_hash": "50858481ee2b36fcb47f5198652fb5d43e5c4b5a0a3047336435fa95", + "stdout_hash": "96e2cc44060176eee134eb3c84c96f84d72a8f3c23a6a8973d765e19", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_277-2406dc4.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_277-2406dc4.stdout index 767ae7a34d9..1b070c37a83 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_277-2406dc4.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_277-2406dc4.stdout @@ -96,7 +96,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __gpu_sec_i; int __gpu_sec_i1; int j; - const int m = 3; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } @@ -221,7 +220,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_1( float* __workspace_5, float* __workspace_6) { - int n = __scalar_args.n; int __dim_c_0 = __scalar_args.__dim_c_0; int __dim_out_0 = __scalar_args.__dim_out_0; int __workspace_extent = __scalar_args.__workspace_extent; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_289-b8995a9.json b/tests/reference/gpu_cuda_kernel-gpu_metal_289-b8995a9.json index bf51d940129..df5874e4f8b 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_289-b8995a9.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_289-b8995a9.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_289-b8995a9.stdout", - "stdout_hash": "77fdfea13538e602247f2badad4a243fbf2b71f90e4899057c4c0944", + "stdout_hash": "4f8bd1dd154d280c5a8f0b653db61e69bb8791a10598904e7d90b3fb", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_289-b8995a9.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_289-b8995a9.stdout index 3de9c292483..dac0b61329a 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_289-b8995a9.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_289-b8995a9.stdout @@ -14,7 +14,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( float* __workspace_2) { int nn = __scalar_args.nn; - int __dim_r_0 = __scalar_args.__dim_r_0; int __lb_r_0 = __scalar_args.__lb_r_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; @@ -63,7 +62,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_1( float* __workspace_2) { int nn = __scalar_args.nn; - int __dim_r_0 = __scalar_args.__dim_r_0; int __lb_r_0 = __scalar_args.__lb_r_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_290-febb906.json b/tests/reference/gpu_cuda_kernel-gpu_metal_290-febb906.json index e40acb27fca..b6f0280e306 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_290-febb906.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_290-febb906.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_290-febb906.stdout", - "stdout_hash": "03855f4a849a1b605d5c09f42c3545fa60543429074aff62f3a7bbc5", + "stdout_hash": "9df77c37b066e770e2d1cb7da349db7f701c07c655b88ac34df353f2", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_290-febb906.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_290-febb906.stdout index 96a633915c3..83003c4bc0e 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_290-febb906.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_290-febb906.stdout @@ -14,7 +14,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( float* __workspace_2) { int nn = __scalar_args.nn; - int __dim_r_0 = __scalar_args.__dim_r_0; int __lb_r_0 = __scalar_args.__lb_r_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_291-460362f.json b/tests/reference/gpu_cuda_kernel-gpu_metal_291-460362f.json index 9687e8244fe..91101fb5713 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_291-460362f.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_291-460362f.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_291-460362f.stdout", - "stdout_hash": "d15a32de92c63bdf19cee98429e3088049eb7d18faf5aed060f23bd2", + "stdout_hash": "d99de52818c45429d07edaf81c76bf4e7d9615cf37e42da07a967aad", "stderr": "gpu_cuda_kernel-gpu_metal_291-460362f.stderr", "stderr_hash": "64a8815f47348eb18517c2672487367a4ab1c69a822bd593c1a3703c", "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_291-460362f.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_291-460362f.stdout index e2fcc9b18b6..f87a577c7f4 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_291-460362f.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_291-460362f.stdout @@ -10,7 +10,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( float* r, __ScalarArgs___lfortran_gpu_kernel_0 __scalar_args) { - int __dim_r_0 = __scalar_args.__dim_r_0; int __lb_r_0 = __scalar_args.__lb_r_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __flat_idx; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_292-0dd7a4a.json b/tests/reference/gpu_cuda_kernel-gpu_metal_292-0dd7a4a.json index 883b7f9aac7..7f62df9833f 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_292-0dd7a4a.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_292-0dd7a4a.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_292-0dd7a4a.stdout", - "stdout_hash": "77fdfea13538e602247f2badad4a243fbf2b71f90e4899057c4c0944", + "stdout_hash": "4f8bd1dd154d280c5a8f0b653db61e69bb8791a10598904e7d90b3fb", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_292-0dd7a4a.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_292-0dd7a4a.stdout index 3de9c292483..dac0b61329a 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_292-0dd7a4a.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_292-0dd7a4a.stdout @@ -14,7 +14,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( float* __workspace_2) { int nn = __scalar_args.nn; - int __dim_r_0 = __scalar_args.__dim_r_0; int __lb_r_0 = __scalar_args.__lb_r_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; @@ -63,7 +62,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_1( float* __workspace_2) { int nn = __scalar_args.nn; - int __dim_r_0 = __scalar_args.__dim_r_0; int __lb_r_0 = __scalar_args.__lb_r_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_296-10ab30d.json b/tests/reference/gpu_cuda_kernel-gpu_metal_296-10ab30d.json index 8585a93604e..a81144248bb 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_296-10ab30d.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_296-10ab30d.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_296-10ab30d.stdout", - "stdout_hash": "9590916c11124c74e5a45476309affa7b42fa24ea35aa4b33301d9c2", + "stdout_hash": "bc078dafb5c77a598257dea162429bd671c64a50c427ce7231bb5f27", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_296-10ab30d.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_296-10ab30d.stdout index a263814c8a4..5b918224c86 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_296-10ab30d.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_296-10ab30d.stdout @@ -29,12 +29,9 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( __ScalarArgs___lfortran_gpu_kernel_0 __scalar_args, float* __workspace_9) { - int nn = __scalar_args.nn; int __dim_out_0 = __scalar_args.__dim_out_0; int __lb_out_0 = __scalar_args.__lb_out_0; - int __dim_out_1 = __scalar_args.__dim_out_1; int __lb_out_1 = __scalar_args.__lb_out_1; - int __dim_s_0 = __scalar_args.__dim_s_0; int __lb_s_0 = __scalar_args.__lb_s_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_298-e543a30.json b/tests/reference/gpu_cuda_kernel-gpu_metal_298-e543a30.json index 8111814d5b5..c70a868f547 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_298-e543a30.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_298-e543a30.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_298-e543a30.stdout", - "stdout_hash": "3d091ebc71b8fffaee968524a52e1f0a06bf804a3224d2cbbe5ca045", + "stdout_hash": "4e28f430d3a3d4c6783ff1b8327024ed9a95b7d511d698149507a668", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_298-e543a30.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_298-e543a30.stdout index 029884ca5fb..0b29a533205 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_298-e543a30.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_298-e543a30.stdout @@ -63,7 +63,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_1( int __loop_end_0 = __scalar_args.__loop_end_0; int __flat_idx; int i; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } @@ -91,7 +90,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_2( int __flat_idx; int __gpu_elem_i; int i; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } @@ -135,7 +133,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_3( int __loop_end_0 = __scalar_args.__loop_end_0; int __flat_idx; int i; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } @@ -163,7 +160,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_4( int __loop_end_0 = __scalar_args.__loop_end_0; int __flat_idx; int i; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_302-c945ed1.json b/tests/reference/gpu_cuda_kernel-gpu_metal_302-c945ed1.json index b8922526216..985695ee8f8 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_302-c945ed1.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_302-c945ed1.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_302-c945ed1.stdout", - "stdout_hash": "f1021900d0f8de07660fd5f42ca054903c56b6bf09ef7407e5b31fc0", + "stdout_hash": "b5b47d78f67794b80722bc5c24b3f707b84ad5b277a409b3e652268e", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_302-c945ed1.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_302-c945ed1.stdout index 7d913fd8a2c..e1f361c8b53 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_302-c945ed1.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_302-c945ed1.stdout @@ -14,7 +14,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __flat_idx; int __gpu_elem_i; int i; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_304-0ced324.json b/tests/reference/gpu_cuda_kernel-gpu_metal_304-0ced324.json index ed4fe92c8cb..52370cebffd 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_304-0ced324.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_304-0ced324.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_304-0ced324.stdout", - "stdout_hash": "560dcae0d6e6ccbdc74988b4012b3967927b02767e0dfcb0a1a73772", + "stdout_hash": "50e500c7965c29e469174d4828f2b1d1579a4f2e146138ce887f3001", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_304-0ced324.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_304-0ced324.stdout index b3c2dabcd12..0868cad7c9a 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_304-0ced324.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_304-0ced324.stdout @@ -13,7 +13,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __flat_idx; int __gpu_elem_i; int i; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_307-eb7dd8e.json b/tests/reference/gpu_cuda_kernel-gpu_metal_307-eb7dd8e.json index bd75aec7ea9..4fc68712290 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_307-eb7dd8e.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_307-eb7dd8e.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_307-eb7dd8e.stdout", - "stdout_hash": "dfb8a50d13ec328e56638d508ef190da5351b50bd4c7b5e708cb1bd9", + "stdout_hash": "50afe591e8ffa51f967d5cae1b4f7255a5fb01ef492ef63978e405d2", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_307-eb7dd8e.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_307-eb7dd8e.stdout index 2b9f949247b..1f68f1fdc08 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_307-eb7dd8e.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_307-eb7dd8e.stdout @@ -13,8 +13,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( __ScalarArgs___lfortran_gpu_kernel_0 __scalar_args, float* __workspace_2) { - int nn = __scalar_args.nn; - int __dim_r_0 = __scalar_args.__dim_r_0; int __lb_r_0 = __scalar_args.__lb_r_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_309-c5214d3.json b/tests/reference/gpu_cuda_kernel-gpu_metal_309-c5214d3.json index e743450e414..69bdce2dbfb 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_309-c5214d3.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_309-c5214d3.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_309-c5214d3.stdout", - "stdout_hash": "027e6304b8a6fca4c3fc21b8a7cad2af5a3aed789baff2b508b3b7ee", + "stdout_hash": "d43f89c4f6ee0568f138089054a3ad9d5d8dbcf91216dae2f52e4d94", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_309-c5214d3.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_309-c5214d3.stdout index 2115baa01f8..0d5fd2227a8 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_309-c5214d3.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_309-c5214d3.stdout @@ -22,7 +22,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( __ScalarArgs___lfortran_gpu_kernel_0 __scalar_args, float* __workspace_3) { - int __dim_r_0 = __scalar_args.__dim_r_0; int __lb_r_0 = __scalar_args.__lb_r_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_310-c1a4744.json b/tests/reference/gpu_cuda_kernel-gpu_metal_310-c1a4744.json index c06ba719fea..3f2cacbc8dc 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_310-c1a4744.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_310-c1a4744.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_310-c1a4744.stdout", - "stdout_hash": "21a7cbec50c12c8ce7240556934232577cf5802617516935aac7bfd7", + "stdout_hash": "f874ef7daa0c5975f3649f77b165494a8d34da1b81c4d144c34613d8", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_310-c1a4744.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_310-c1a4744.stdout index 87378b3b9e7..38253ca125f 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_310-c1a4744.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_310-c1a4744.stdout @@ -38,7 +38,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( float* __workspace_2) { int nn = __scalar_args.nn; - int __dim_r_0 = __scalar_args.__dim_r_0; int __lb_r_0 = __scalar_args.__lb_r_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_316-6447449.json b/tests/reference/gpu_cuda_kernel-gpu_metal_316-6447449.json index d8f1c304310..15cf2e540d8 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_316-6447449.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_316-6447449.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_316-6447449.stdout", - "stdout_hash": "5b5ec403ddf5698a82e8ef19195d4528a5d6452c499b203da47dcf82", + "stdout_hash": "466be5262268a5a8323b1a6efe8cd9c5d1fdd32365d525bc3e7298e0", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_316-6447449.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_316-6447449.stdout index fe959d3da40..074641d6ace 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_316-6447449.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_316-6447449.stdout @@ -25,7 +25,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __lb_p_0 = __scalar_args.__lb_p_0; int __dim_p_1 = __scalar_args.__dim_p_1; int __lb_p_1 = __scalar_args.__lb_p_1; - int __dim_p_2 = __scalar_args.__dim_p_2; int __lb_p_2 = __scalar_args.__lb_p_2; int __flat_idx; int i; @@ -57,7 +56,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_1( int __lb_p_0 = __scalar_args.__lb_p_0; int __dim_p_1 = __scalar_args.__dim_p_1; int __lb_p_1 = __scalar_args.__lb_p_1; - int __dim_p_2 = __scalar_args.__dim_p_2; int __lb_p_2 = __scalar_args.__lb_p_2; int __flat_idx; int i; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_317-ecc259a.json b/tests/reference/gpu_cuda_kernel-gpu_metal_317-ecc259a.json index 7649a43c8a0..5adab5111ae 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_317-ecc259a.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_317-ecc259a.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_317-ecc259a.stdout", - "stdout_hash": "2701ce45a4b018b85871a25fabe3bd8cfbde12c0181d8782113eab92", + "stdout_hash": "d73cff5f043d91df1c7aa52bbb265920135fec7a807821ced2a50471", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_317-ecc259a.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_317-ecc259a.stdout index af3167e5245..f7bdc6ef007 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_317-ecc259a.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_317-ecc259a.stdout @@ -29,11 +29,9 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( { int __dim___gpu_gather_ops___upper__0 = __scalar_args.__dim___gpu_gather_ops___upper__0; int __lb___gpu_gather_ops___upper__0 = __scalar_args.__lb___gpu_gather_ops___upper__0; - int __dim___gpu_gather_ops___upper__1 = __scalar_args.__dim___gpu_gather_ops___upper__1; int __lb___gpu_gather_ops___upper__1 = __scalar_args.__lb___gpu_gather_ops___upper__1; int __dim___gpu_gather_ops_1__upper__0 = __scalar_args.__dim___gpu_gather_ops_1__upper__0; int __lb___gpu_gather_ops_1__upper__0 = __scalar_args.__lb___gpu_gather_ops_1__upper__0; - int __dim___gpu_gather_ops_1__upper__1 = __scalar_args.__dim___gpu_gather_ops_1__upper__1; int __lb___gpu_gather_ops_1__upper__1 = __scalar_args.__lb___gpu_gather_ops_1__upper__1; int __flat_idx; int i; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_318-5a5bfbd.json b/tests/reference/gpu_cuda_kernel-gpu_metal_318-5a5bfbd.json index 3eeb3ed6645..f9ebc7fda83 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_318-5a5bfbd.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_318-5a5bfbd.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_318-5a5bfbd.stdout", - "stdout_hash": "2dc0d237dc610c45427e9faad7358169ae86dd231bd0a92c2d8d1485", + "stdout_hash": "dfb694c27af0b9cdbb92e9a0a034a4d9170582abfeb728b211d02b04", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_318-5a5bfbd.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_318-5a5bfbd.stdout index 9f8ba76eec1..d2ba1d27f92 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_318-5a5bfbd.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_318-5a5bfbd.stdout @@ -30,7 +30,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __gpu_sec_i; int __gpu_sec_i1; int k; - const int ny = 3; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_320-082cdda.json b/tests/reference/gpu_cuda_kernel-gpu_metal_320-082cdda.json index 1af419a1fd7..b73dca38190 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_320-082cdda.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_320-082cdda.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_320-082cdda.stdout", - "stdout_hash": "98e5c57f4e8930db0f9fc20a523d1f3438272e074387663fc612b941", + "stdout_hash": "85446dcfd7e2585ffa1abd28333c49eff5809d5577b02600b6205bcf", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_320-082cdda.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_320-082cdda.stdout index 27efbe19f71..a016fa10d8d 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_320-082cdda.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_320-082cdda.stdout @@ -22,9 +22,7 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( float* __data_self_op__a, __ScalarArgs___lfortran_gpu_kernel_0 __scalar_args) { - int __size_self_op__a = __scalar_args.__size_self_op__a; int __lb_self_op__a_dim1 = __scalar_args.__lb_self_op__a_dim1; - int __1__data_self_op__a = __scalar_args.__1__data_self_op__a; int __flat_idx; int i; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= 3)) { @@ -48,9 +46,7 @@ extern "C" __global__ void __lfortran_gpu_kernel_1( float* __data_self_op__a, __ScalarArgs___lfortran_gpu_kernel_1 __scalar_args) { - int __size_self_op__a = __scalar_args.__size_self_op__a; int __lb_self_op__a_dim1 = __scalar_args.__lb_self_op__a_dim1; - int __1__data_self_op__a = __scalar_args.__1__data_self_op__a; int __flat_idx; int i; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= 3)) { diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_328-cc3334c.json b/tests/reference/gpu_cuda_kernel-gpu_metal_328-cc3334c.json index 598fb8ee636..351629d6f3a 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_328-cc3334c.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_328-cc3334c.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_328-cc3334c.stdout", - "stdout_hash": "e4a8ed57b1dcba844792e498965cf2b8d9a5f988856f0e45e0d618e1", + "stdout_hash": "5f767bffdddc77b9bcff702899849dd6aeac80d3a710d83cd55c8a26", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_328-cc3334c.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_328-cc3334c.stdout index a7a5ed98bc3..7ecaa4fca64 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_328-cc3334c.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_328-cc3334c.stdout @@ -1,7 +1,6 @@ #include __device__ inline void fixed_result_device_t_gpu_54(int n, float* r) { - const int width = 2; int __1__libasr_index_; int __do_loop_end; int __do_loop_end1; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_334-124b176.json b/tests/reference/gpu_cuda_kernel-gpu_metal_334-124b176.json index 78b648c8aef..4f106e4e581 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_334-124b176.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_334-124b176.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_334-124b176.stdout", - "stdout_hash": "b5df98b3c3758c30ae957c191218af3bed4ac7a20623a9cd36e21c20", + "stdout_hash": "65442cd378dca77fe4fe2d2af90784876ddbfc61a0b95ec80fa5d9cd", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_334-124b176.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_334-124b176.stdout index fc1443c1340..cc60ae9dcfb 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_334-124b176.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_334-124b176.stdout @@ -12,7 +12,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __loop_end_0 = __scalar_args.__loop_end_0; int __flat_idx; int i; - const int n = 8; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } @@ -40,7 +39,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_1( int __loop_end_0 = __scalar_args.__loop_end_0; int __flat_idx; int i; - const int n = 8; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_337-9610a4e.json b/tests/reference/gpu_cuda_kernel-gpu_metal_337-9610a4e.json index 2bf4a384a02..aab6fa12ba3 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_337-9610a4e.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_337-9610a4e.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_337-9610a4e.stdout", - "stdout_hash": "4f94aa76bc9d77726e9321a45553dc410d6297bdb332220311aab242", + "stdout_hash": "badc1044969e9952c82084f9953821be339cab1c12a90d084d83a301", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_337-9610a4e.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_337-9610a4e.stdout index 363c079a25a..22e4c4660f5 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_337-9610a4e.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_337-9610a4e.stdout @@ -12,7 +12,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __loop_end_0 = __scalar_args.__loop_end_0; int __flat_idx; int i; - const int n = 8; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_391-0cf1271.json b/tests/reference/gpu_cuda_kernel-gpu_metal_391-0cf1271.json index de2def84037..d88924fb599 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_391-0cf1271.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_391-0cf1271.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_391-0cf1271.stdout", - "stdout_hash": "0606cf07c177414a36c5b16ab0aa924217e6c642dbb5c68dce923694", + "stdout_hash": "43e240ed1ec81d67988ad74e469c301289ca1dd5e21fed69ad08ef9e", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_391-0cf1271.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_391-0cf1271.stdout index 0693d6205dc..3417b399e40 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_391-0cf1271.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_391-0cf1271.stdout @@ -29,7 +29,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __flat_idx; float* __gpu_heap_view___gpu_call_result; int i; - const int m = 8; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_408-553c2f1.json b/tests/reference/gpu_cuda_kernel-gpu_metal_408-553c2f1.json index fd5628c0521..c249922998e 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_408-553c2f1.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_408-553c2f1.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_408-553c2f1.stdout", - "stdout_hash": "3d866b8fa3ccdc6c2f73ea09035cab63bfe70c09628d496f4d587ad3", + "stdout_hash": "9cd50c8979e271ac58a0fd8564ccc7bfefedc48d7fb3c0751a687ae1", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_408-553c2f1.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_408-553c2f1.stdout index ed8870165fb..8e8a1ee9b41 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_408-553c2f1.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_408-553c2f1.stdout @@ -88,7 +88,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __gpu_stop_code; int __gpu_stop_site; int i; - const int n = 64; __gpu_stop_site = 0; __gpu_stop_code = 0; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_452-b86afe3.json b/tests/reference/gpu_cuda_kernel-gpu_metal_452-b86afe3.json index 68faff85b1f..17fad04e0a9 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_452-b86afe3.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_452-b86afe3.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_452-b86afe3.stdout", - "stdout_hash": "c694aed1c48d67e433eae05ea5ac4583035d7cbd9516045eef89cae5", + "stdout_hash": "be066782aeef4f94b52e93d890e4c22b798f86d1443326dc5533a410", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_452-b86afe3.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_452-b86afe3.stdout index f871a2d93c9..5e212877748 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_452-b86afe3.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_452-b86afe3.stdout @@ -47,7 +47,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __gpu_sum_k; float __gpu_sum_res; const int n = 3; - const int np = 2; int p; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_453-087cbdb.json b/tests/reference/gpu_cuda_kernel-gpu_metal_453-087cbdb.json index e02996a5e9d..1eb9f5fc53a 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_453-087cbdb.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_453-087cbdb.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_453-087cbdb.stdout", - "stdout_hash": "f79985a43162ce12966801fca41ea38df935ce1ac14d13646f20cc78", + "stdout_hash": "f8df5221e2a836cd4e67bab97ee8b3ab21b90f4b9d3d20dddd43a697", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_453-087cbdb.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_453-087cbdb.stdout index 3635a02db08..31bbd97c508 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_453-087cbdb.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_453-087cbdb.stdout @@ -37,7 +37,6 @@ __device__ inline void twice_gpu_44(float* x, int __size_x_dim1, int __stride_x_ } __device__ inline void points_device_t_gpu_62(int p, int n, point_t* r) { - int __1_intent_out_dealloc_idx_; int __do_loop_end; int i; __do_loop_end = n; @@ -108,7 +107,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __gpu_sec_i1; int __gpu_sec_i2; const int n = 3; - const int np = 2; int p; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_455-ec807a4.json b/tests/reference/gpu_cuda_kernel-gpu_metal_455-ec807a4.json index 6029c86cb24..f768ab7921d 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_455-ec807a4.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_455-ec807a4.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_455-ec807a4.stdout", - "stdout_hash": "edb134fd25365b4c6720108a2fd91aae8ba93f9b2e4de447ffec0254", + "stdout_hash": "1036588b5a1216a09d038fab83732527e026746382d0d070f9007c57", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_455-ec807a4.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_455-ec807a4.stdout index ce88c06747a..8f621c64706 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_455-ec807a4.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_455-ec807a4.stdout @@ -53,7 +53,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __gpu_mm_k5; const int m = 4; const int n = 3; - const int np = 2; int p; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_474-0583450.json b/tests/reference/gpu_cuda_kernel-gpu_metal_474-0583450.json index 817bba7c597..2db4696deeb 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_474-0583450.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_474-0583450.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_474-0583450.stdout", - "stdout_hash": "f6f0f5651c82a9a53c4edd92d61d0080479570398c0f266be86eec64", + "stdout_hash": "9aeae5a07d29532a2543236859e7a997c1a98675868d1dfa45bad359", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_474-0583450.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_474-0583450.stdout index 39d38424a11..5359080912e 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_474-0583450.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_474-0583450.stdout @@ -15,7 +15,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int j; int k; const int m = 64; - const int n = 10000; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } @@ -57,7 +56,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_1( int __gpu_sec_i; int j; const int m = 64; - const int n = 10000; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } @@ -104,7 +102,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_2( int __loop_end_0 = __scalar_args.__loop_end_0; int __flat_idx; int j; - const int n = 10000; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } @@ -114,40 +111,42 @@ extern "C" __global__ void __lfortran_gpu_kernel_2( } extern "C" __global__ void __lfortran_gpu_kernel_3( - float* __libasr__created__var__0__array_constant_, float* u, float* y) { int __1_k; int __flat_idx; int __gpu_elem_i1; - int __gpu_sum_k; - float __gpu_sum_res; int j; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= 1)) { return; } __flat_idx = ((blockIdx.x * blockDim.x) + threadIdx.x); j = (__flat_idx + 1); - __1_k = 1; - __libasr__created__var__0__array_constant_[((int)(__1_k) - (1))] = 1.00000000000000000e+00f; - __1_k = 2; - __libasr__created__var__0__array_constant_[((int)(__1_k) - (1))] = 2.00000000000000000e+00f; - __1_k = 3; - __libasr__created__var__0__array_constant_[((int)(__1_k) - (1))] = 3.00000000000000000e+00f; - __1_k = 4; - __libasr__created__var__0__array_constant_[((int)(__1_k) - (1))] = 4.00000000000000000e+00f; - __gpu_elem_i1 = (1 - 1); - while (((__gpu_elem_i1 + 1) <= 4)) { - __gpu_elem_i1 = (__gpu_elem_i1 + 1); - u[((int)(__gpu_elem_i1) - (1))] = (__libasr__created__var__0__array_constant_[((int)(__gpu_elem_i1) - (1))] * ((float)j)); - } - __gpu_sum_res = 0.00000000000000000e+00f; - __gpu_sum_k = (1 - 1); - while (((__gpu_sum_k + 1) <= 4)) { - __gpu_sum_k = (__gpu_sum_k + 1); - __gpu_sum_res = (__gpu_sum_res + u[((int)(__gpu_sum_k) - (1))]); + { + int __gpu_sum_k; + float __gpu_sum_res; + float __libasr__created__var__0__array_constant_[4]; + __1_k = 1; + __libasr__created__var__0__array_constant_[((int)(__1_k) - (1))] = 1.00000000000000000e+00f; + __1_k = 2; + __libasr__created__var__0__array_constant_[((int)(__1_k) - (1))] = 2.00000000000000000e+00f; + __1_k = 3; + __libasr__created__var__0__array_constant_[((int)(__1_k) - (1))] = 3.00000000000000000e+00f; + __1_k = 4; + __libasr__created__var__0__array_constant_[((int)(__1_k) - (1))] = 4.00000000000000000e+00f; + __gpu_elem_i1 = (1 - 1); + while (((__gpu_elem_i1 + 1) <= 4)) { + __gpu_elem_i1 = (__gpu_elem_i1 + 1); + u[((int)(__gpu_elem_i1) - (1))] = (__libasr__created__var__0__array_constant_[((int)(__gpu_elem_i1) - (1))] * ((float)j)); + } + __gpu_sum_res = 0.00000000000000000e+00f; + __gpu_sum_k = (1 - 1); + while (((__gpu_sum_k + 1) <= 4)) { + __gpu_sum_k = (__gpu_sum_k + 1); + __gpu_sum_res = (__gpu_sum_res + u[((int)(__gpu_sum_k) - (1))]); + } + y[((int)(j) - (1))] = __gpu_sum_res; } - y[((int)(j) - (1))] = __gpu_sum_res; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_476-6b797c7.json b/tests/reference/gpu_cuda_kernel-gpu_metal_476-6b797c7.json index 536141c59f9..5c7ab8f7673 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_476-6b797c7.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_476-6b797c7.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_476-6b797c7.stdout", - "stdout_hash": "b804252a7b704ff02e6913c35ee03b5fcbb598c0187358ad3455b0d7", + "stdout_hash": "b55d07215b7fa1a9e5514715ac487b991f0ce35621925b831d1cf3a3", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_476-6b797c7.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_476-6b797c7.stdout index 180a2d2b635..23afdbde242 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_476-6b797c7.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_476-6b797c7.stdout @@ -14,7 +14,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int j; int k; const int m = 150000; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } @@ -47,8 +46,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_1( float* __workspace_2) { int __gpu_private_shape = __scalar_args.__gpu_private_shape; - int n = __scalar_args.n; - int __dim_y_0 = __scalar_args.__dim_y_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; int __flat_idx; @@ -98,8 +95,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_2( { int __gpu_private_shape = __scalar_args.__gpu_private_shape; int m = __scalar_args.m; - int n = __scalar_args.n; - int __dim_y_0 = __scalar_args.__dim_y_0; int __loop_end_0 = __scalar_args.__loop_end_0; int __workspace_extent = __scalar_args.__workspace_extent; int __flat_idx; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_477-3f086b7.json b/tests/reference/gpu_cuda_kernel-gpu_metal_477-3f086b7.json index c41ddcc2170..0f42eecfb69 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_477-3f086b7.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_477-3f086b7.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_477-3f086b7.stdout", - "stdout_hash": "8ae50e65a6e28677ee0bdb8ba33d46772b0a72c64e75d557d2be0e6f", + "stdout_hash": "5378fd95b1e4a2f26b4490e0188dfd21070a6b8395e1752cb1687ebd", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_477-3f086b7.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_477-3f086b7.stdout index 5519e43f6d6..0479fb87976 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_477-3f086b7.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_477-3f086b7.stdout @@ -41,7 +41,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( float __gpu_scalar_argument; float* __libasr_created__subroutine_call_work; int j; - const int n = 4; float w[256]; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; @@ -92,7 +91,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_1( int __loop_end_0 = __scalar_args.__loop_end_0; int __flat_idx; int j; - const int n = 4; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_478-5c1241e.json b/tests/reference/gpu_cuda_kernel-gpu_metal_478-5c1241e.json index af7d7f91d02..5136d07e033 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_478-5c1241e.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_478-5c1241e.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_478-5c1241e.stdout", - "stdout_hash": "8ca01d307d65f1d554cca745d04fd700a916110fe782b16fe19bc9bc", + "stdout_hash": "3cf14650618efe8b5a136d599dd1fb730040f08068900b88cba8b7ff", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_478-5c1241e.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_478-5c1241e.stdout index 8113065b28c..a87b7dfe64e 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_478-5c1241e.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_478-5c1241e.stdout @@ -11,9 +11,7 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( float* y, __ScalarArgs___lfortran_gpu_kernel_0 __scalar_args) { - int __lcompilers_t_extent_1 = __scalar_args.__lcompilers_t_extent_1; int m = __scalar_args.m; - int __dim_t_0 = __scalar_args.__dim_t_0; int __do_loop_end; int __flat_idx; int j; diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_479-7e99684.json b/tests/reference/gpu_cuda_kernel-gpu_metal_479-7e99684.json index 39590267386..985769e2b46 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_479-7e99684.json +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_479-7e99684.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_cuda_kernel-gpu_metal_479-7e99684.stdout", - "stdout_hash": "9dc278827717c80ec55d0e005ac1e950a700171dd5801c98602aeddb", + "stdout_hash": "1cbb05b39c023ec98c7646aa213ba8fee4bfe8956dc004ef75839cc1", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_cuda_kernel-gpu_metal_479-7e99684.stdout b/tests/reference/gpu_cuda_kernel-gpu_metal_479-7e99684.stdout index 8a6013d89c4..0d768c22bb2 100644 --- a/tests/reference/gpu_cuda_kernel-gpu_metal_479-7e99684.stdout +++ b/tests/reference/gpu_cuda_kernel-gpu_metal_479-7e99684.stdout @@ -18,7 +18,6 @@ extern "C" __global__ void __lfortran_gpu_kernel_0( int __flat_idx; int __gpu_bc_i; int j; - const int n = 32; if ((((blockIdx.x * blockDim.x) + threadIdx.x) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; } diff --git a/tests/reference/gpu_metal_kernel-gpu_kernel_source_14-4e9d9d4.json b/tests/reference/gpu_metal_kernel-gpu_kernel_source_14-4e9d9d4.json new file mode 100644 index 00000000000..2c03ca7d31c --- /dev/null +++ b/tests/reference/gpu_metal_kernel-gpu_kernel_source_14-4e9d9d4.json @@ -0,0 +1,13 @@ +{ + "basename": "gpu_metal_kernel-gpu_kernel_source_14-4e9d9d4", + "cmd": "lfortran --no-color --gpu=metal --show-gpu-kernel-source {infile}", + "infile": "tests/../integration_tests/gpu_kernel_source_14.f90", + "infile_hash": "57ad8288c319097f019dbae086cd1dfa65b028269532a66e5a61edeb", + "outfile": null, + "outfile_hash": null, + "stdout": "gpu_metal_kernel-gpu_kernel_source_14-4e9d9d4.stdout", + "stdout_hash": "ca87fec75596f4cb9f7cf84bb3af6e421b31ff1e4d130e874bc1655b", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/gpu_metal_kernel-gpu_kernel_source_14-4e9d9d4.stdout b/tests/reference/gpu_metal_kernel-gpu_kernel_source_14-4e9d9d4.stdout new file mode 100644 index 00000000000..4c3b1732493 --- /dev/null +++ b/tests/reference/gpu_metal_kernel-gpu_kernel_source_14-4e9d9d4.stdout @@ -0,0 +1,201 @@ +#include +using namespace metal; + +struct __ScalarArgs___lfortran_gpu_kernel_0 { + int __loop_end_0; + int __gpu_lanes; +}; + +kernel void __lfortran_gpu_kernel_0( + device float* g [[buffer(0)]], + device float* x [[buffer(1)]], + constant __ScalarArgs___lfortran_gpu_kernel_0& __scalar_args [[buffer(2)]], + uint __gpu_grid_thread [[thread_position_in_grid]], + uint __gpu_simd_lane [[thread_index_in_simdgroup]]) +{ + int __loop_end_0 = __scalar_args.__loop_end_0; + int __gpu_lanes = __scalar_args.__gpu_lanes; + uint __thread_id = __gpu_grid_thread / (uint)__gpu_lanes; + int __gpu_lane = (int)(__gpu_grid_thread % (uint)__gpu_lanes); + int __flat_idx; + int __gpu_elem_i; + int __gpu_sec_i; + int j; + const int n = 8; + if ((((0 * 0) + __thread_id) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { + return; + } + __flat_idx = ((0 * 0) + __thread_id); + j = (__flat_idx + 1); + { + float t[4]; + { + int __1__libasr_index_; + int __do_loop_end; + int __do_loop_inc; + int __gpu_loop_end; + int __gpu_loop_group; + float __libasr__created__var__0__array_constructor_[4]; + float e; + __1__libasr_index_ = 1; + __libasr__created__var__0__array_constructor_[((int)(__1__libasr_index_) - (1))] = x[((int)(j) - (1))]; + __1__libasr_index_ = (__1__libasr_index_ + 1); + __libasr__created__var__0__array_constructor_[((int)(__1__libasr_index_) - (1))] = ( 1.00000000000000000e+01 * x[((int)(j) - (1))]); + __1__libasr_index_ = (__1__libasr_index_ + 1); + __libasr__created__var__0__array_constructor_[((int)(__1__libasr_index_) - (1))] = (( 1.00000000000000000e+01 * x[((int)(j) - (1))]) + 1.00000000000000000e+00); + __1__libasr_index_ = (__1__libasr_index_ + 1); + __libasr__created__var__0__array_constructor_[((int)(__1__libasr_index_) - (1))] = (( 1.00000000000000000e+01 * x[((int)(j) - (1))]) + 2.00000000000000000e+00); + __1__libasr_index_ = (__1__libasr_index_ + 1); + __gpu_loop_end = 4; + __gpu_elem_i = 1; + if ((__gpu_loop_end >= 1)) { + for (__gpu_loop_group = 1; __gpu_loop_group <= (__gpu_loop_end - 15); __gpu_loop_group += 16) { + __gpu_elem_i = __gpu_loop_group; + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + __gpu_elem_i = (__gpu_loop_group + 1); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + __gpu_elem_i = (__gpu_loop_group + 2); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + __gpu_elem_i = (__gpu_loop_group + 3); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + __gpu_elem_i = (__gpu_loop_group + 4); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + __gpu_elem_i = (__gpu_loop_group + 5); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + __gpu_elem_i = (__gpu_loop_group + 6); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + __gpu_elem_i = (__gpu_loop_group + 7); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + __gpu_elem_i = (__gpu_loop_group + 8); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + __gpu_elem_i = (__gpu_loop_group + 9); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + __gpu_elem_i = (__gpu_loop_group + 10); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + __gpu_elem_i = (__gpu_loop_group + 11); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + __gpu_elem_i = (__gpu_loop_group + 12); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + __gpu_elem_i = (__gpu_loop_group + 13); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + __gpu_elem_i = (__gpu_loop_group + 14); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + __gpu_elem_i = (__gpu_loop_group + 15); + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + } + for (__gpu_elem_i = __gpu_loop_group; __gpu_elem_i <= __gpu_loop_end; __gpu_elem_i++) { + t[((int)(__gpu_elem_i) - (1))] = __libasr__created__var__0__array_constructor_[((int)(__gpu_elem_i) - (1))]; + } + } + __do_loop_end = ((((int)4) + ((int)1)) - 1); + __do_loop_inc = (1 * ((int)__gpu_lanes)); + __gpu_sec_i = ((1 + (((int)__gpu_lane) * 1)) - __do_loop_inc); + while (((int)(((int)((__do_loop_inc > 0) && ((__gpu_sec_i + __do_loop_inc) <= __do_loop_end))) || ((int)((__do_loop_inc <= 0) && ((__gpu_sec_i + __do_loop_inc) >= __do_loop_end)))))) { + __gpu_sec_i = (__gpu_sec_i + __do_loop_inc); + g[((int)(__gpu_sec_i) - (1)) + (4 * ((int)(j) - (1)))] = t[((int)(__gpu_sec_i) - (1))]; + } + if (__gpu_lanes > 1) simdgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup); + } + } +} + +struct __ScalarArgs___lfortran_gpu_kernel_1 { + int __loop_end_0; + int __gpu_lanes; +}; + +kernel void __lfortran_gpu_kernel_1( + device float* g [[buffer(0)]], + device float* x [[buffer(1)]], + constant __ScalarArgs___lfortran_gpu_kernel_1& __scalar_args [[buffer(2)]], + uint __gpu_grid_thread [[thread_position_in_grid]], + uint __gpu_simd_lane [[thread_index_in_simdgroup]]) +{ + int __loop_end_0 = __scalar_args.__loop_end_0; + int __gpu_lanes = __scalar_args.__gpu_lanes; + uint __thread_id = __gpu_grid_thread / (uint)__gpu_lanes; + int __gpu_lane = (int)(__gpu_grid_thread % (uint)__gpu_lanes); + int __1__libasr_index_; + int __flat_idx; + int __gpu_elem_i1; + int __gpu_sec_i1; + int j; + const int n = 8; + if ((((0 * 0) + __thread_id) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { + return; + } + __flat_idx = ((0 * 0) + __thread_id); + j = (__flat_idx + 1); + { + int __do_loop_end; + int __do_loop_inc; + int __gpu_loop_end; + int __gpu_loop_group; + float __libasr__created__var__1__array_constructor_[4]; + float t[4]; + float u[4]; + __1__libasr_index_ = 1; + __libasr__created__var__1__array_constructor_[((int)(__1__libasr_index_) - (1))] = x[((int)(j) - (1))]; + __1__libasr_index_ = (__1__libasr_index_ + 1); + __libasr__created__var__1__array_constructor_[((int)(__1__libasr_index_) - (1))] = ( 2.00000000000000000e+00 * x[((int)(j) - (1))]); + __1__libasr_index_ = (__1__libasr_index_ + 1); + __libasr__created__var__1__array_constructor_[((int)(__1__libasr_index_) - (1))] = ( 3.00000000000000000e+00 * x[((int)(j) - (1))]); + __1__libasr_index_ = (__1__libasr_index_ + 1); + __libasr__created__var__1__array_constructor_[((int)(__1__libasr_index_) - (1))] = ( 4.00000000000000000e+00 * x[((int)(j) - (1))]); + __1__libasr_index_ = (__1__libasr_index_ + 1); + __gpu_loop_end = 4; + __gpu_elem_i1 = 1; + if ((__gpu_loop_end >= 1)) { + for (__gpu_loop_group = 1; __gpu_loop_group <= (__gpu_loop_end - 15); __gpu_loop_group += 16) { + __gpu_elem_i1 = __gpu_loop_group; + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + __gpu_elem_i1 = (__gpu_loop_group + 1); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + __gpu_elem_i1 = (__gpu_loop_group + 2); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + __gpu_elem_i1 = (__gpu_loop_group + 3); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + __gpu_elem_i1 = (__gpu_loop_group + 4); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + __gpu_elem_i1 = (__gpu_loop_group + 5); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + __gpu_elem_i1 = (__gpu_loop_group + 6); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + __gpu_elem_i1 = (__gpu_loop_group + 7); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + __gpu_elem_i1 = (__gpu_loop_group + 8); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + __gpu_elem_i1 = (__gpu_loop_group + 9); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + __gpu_elem_i1 = (__gpu_loop_group + 10); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + __gpu_elem_i1 = (__gpu_loop_group + 11); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + __gpu_elem_i1 = (__gpu_loop_group + 12); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + __gpu_elem_i1 = (__gpu_loop_group + 13); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + __gpu_elem_i1 = (__gpu_loop_group + 14); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + __gpu_elem_i1 = (__gpu_loop_group + 15); + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + } + for (__gpu_elem_i1 = __gpu_loop_group; __gpu_elem_i1 <= __gpu_loop_end; __gpu_elem_i1++) { + t[((int)(__gpu_elem_i1) - (1))] = __libasr__created__var__1__array_constructor_[((int)(__gpu_elem_i1) - (1))]; + } + } + u[((int)(1) - (1))] = t[((int)(4) - (1))]; + u[((int)(2) - (1))] = t[((int)(3) - (1))]; + u[((int)(3) - (1))] = t[((int)(2) - (1))]; + u[((int)(4) - (1))] = t[((int)(1) - (1))]; + __do_loop_end = ((((int)4) + ((int)1)) - 1); + __do_loop_inc = (1 * ((int)__gpu_lanes)); + __gpu_sec_i1 = ((1 + (((int)__gpu_lane) * 1)) - __do_loop_inc); + while (((int)(((int)((__do_loop_inc > 0) && ((__gpu_sec_i1 + __do_loop_inc) <= __do_loop_end))) || ((int)((__do_loop_inc <= 0) && ((__gpu_sec_i1 + __do_loop_inc) >= __do_loop_end)))))) { + __gpu_sec_i1 = (__gpu_sec_i1 + __do_loop_inc); + g[((int)(__gpu_sec_i1) - (1)) + (4 * ((int)(j) - (1)))] = u[((int)(__gpu_sec_i1) - (1))]; + } + if (__gpu_lanes > 1) simdgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup); + } +} + diff --git a/tests/reference/gpu_metal_kernel-gpu_kernel_source_15-ddc1d80.json b/tests/reference/gpu_metal_kernel-gpu_kernel_source_15-ddc1d80.json new file mode 100644 index 00000000000..48a2dbe4260 --- /dev/null +++ b/tests/reference/gpu_metal_kernel-gpu_kernel_source_15-ddc1d80.json @@ -0,0 +1,13 @@ +{ + "basename": "gpu_metal_kernel-gpu_kernel_source_15-ddc1d80", + "cmd": "lfortran --no-color --gpu=metal --show-gpu-kernel-source {infile}", + "infile": "tests/../integration_tests/gpu_kernel_source_15.f90", + "infile_hash": "b548262f1790e25efae0005dfec351f092d5bd7ec7fc20b287feb76d", + "outfile": null, + "outfile_hash": null, + "stdout": "gpu_metal_kernel-gpu_kernel_source_15-ddc1d80.stdout", + "stdout_hash": "31ee2c378a32657d2df48da1e832b3656c97e20d89c74376ab93ad63", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/gpu_metal_kernel-gpu_kernel_source_15-ddc1d80.stdout b/tests/reference/gpu_metal_kernel-gpu_kernel_source_15-ddc1d80.stdout new file mode 100644 index 00000000000..fa609df2747 --- /dev/null +++ b/tests/reference/gpu_metal_kernel-gpu_kernel_source_15-ddc1d80.stdout @@ -0,0 +1,62 @@ +#include +using namespace metal; + +inline float twice_gpu_11(float v) { + float twice; + twice = (((float)2) * v); + return twice; +} + +struct __ScalarArgs___lfortran_gpu_kernel_0 { + float a; + int __dim_x_0; + int __lb_x_0; + int __dim_y_0; + int __lb_y_0; + int __dim_z_0; + int __lb_z_0; + int __dim_z_1; + int __lb_z_1; + int __loop_end_0; + int __gpu_lanes; +}; + +kernel void __lfortran_gpu_kernel_0( + device float* x [[buffer(0)]], + device float* y [[buffer(1)]], + device float* z [[buffer(2)]], + constant __ScalarArgs___lfortran_gpu_kernel_0& __scalar_args [[buffer(3)]], + uint __gpu_grid_thread [[thread_position_in_grid]], + uint __gpu_simd_lane [[thread_index_in_simdgroup]]) +{ + float a = __scalar_args.a; + int __lb_x_0 = __scalar_args.__lb_x_0; + int __lb_y_0 = __scalar_args.__lb_y_0; + int __dim_z_0 = __scalar_args.__dim_z_0; + int __lb_z_0 = __scalar_args.__lb_z_0; + int __lb_z_1 = __scalar_args.__lb_z_1; + int __loop_end_0 = __scalar_args.__loop_end_0; + int __gpu_lanes = __scalar_args.__gpu_lanes; + uint __thread_id = __gpu_grid_thread / (uint)__gpu_lanes; + int __gpu_lane = (int)(__gpu_grid_thread % (uint)__gpu_lanes); + int __flat_idx; + int i; + if ((((0 * 0) + __thread_id) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { + return; + } + __flat_idx = ((0 * 0) + __thread_id); + i = (__flat_idx + 1); + { + float t; + t = (a * x[((int)(i) - (__lb_x_0))]); + if ((__gpu_lane == 0)) { + y[((int)(i) - (__lb_y_0))] = (t + y[((int)(i) - (__lb_y_0))]); + } + if (__gpu_lanes > 1) simdgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup); + } + if ((__gpu_lane == 0)) { + z[((int)(i) - (__lb_z_0)) + (__dim_z_0 * ((int)(2) - (__lb_z_1)))] = twice_gpu_11(y[((int)(i) - (__lb_y_0))]); + } + if (__gpu_lanes > 1) simdgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup); +} + diff --git a/tests/reference/gpu_metal_kernel-gpu_kernel_source_16-6d4e811.json b/tests/reference/gpu_metal_kernel-gpu_kernel_source_16-6d4e811.json new file mode 100644 index 00000000000..c3c53eb6960 --- /dev/null +++ b/tests/reference/gpu_metal_kernel-gpu_kernel_source_16-6d4e811.json @@ -0,0 +1,13 @@ +{ + "basename": "gpu_metal_kernel-gpu_kernel_source_16-6d4e811", + "cmd": "lfortran --no-color --gpu=metal --show-gpu-kernel-source {infile}", + "infile": "tests/../integration_tests/gpu_kernel_source_16.f90", + "infile_hash": "aede8dcc14c79ba45cbbb2144a62c69e47d34bb8e86f294a824b2a02", + "outfile": null, + "outfile_hash": null, + "stdout": "gpu_metal_kernel-gpu_kernel_source_16-6d4e811.stdout", + "stdout_hash": "5eeae32c2dd86af1b752133a768e7dcab2a3ad4bc6ef65b42cfd088a", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/gpu_metal_kernel-gpu_kernel_source_16-6d4e811.stdout b/tests/reference/gpu_metal_kernel-gpu_kernel_source_16-6d4e811.stdout new file mode 100644 index 00000000000..5440b68039f --- /dev/null +++ b/tests/reference/gpu_metal_kernel-gpu_kernel_source_16-6d4e811.stdout @@ -0,0 +1,90 @@ +#include +using namespace metal; + +kernel void __lfortran_gpu_kernel_0( + device float* g [[buffer(0)]], + device float* t [[buffer(1)]], + device float* x [[buffer(2)]], + uint __thread_id [[thread_position_in_grid]]) +{ + int __flat_idx; + int __gpu_bc_i; + int __gpu_loop_end; + int __gpu_loop_group; + int j; + if ((((0 * 0) + __thread_id) >= 1)) { + return; + } + __flat_idx = ((0 * 0) + __thread_id); + j = (__flat_idx + 1); + __gpu_loop_end = 2; + __gpu_bc_i = 1; + if ((__gpu_loop_end >= 1)) { + for (__gpu_loop_group = 1; __gpu_loop_group <= (__gpu_loop_end - 15); __gpu_loop_group += 16) { + __gpu_bc_i = __gpu_loop_group; + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + __gpu_bc_i = (__gpu_loop_group + 1); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + __gpu_bc_i = (__gpu_loop_group + 2); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + __gpu_bc_i = (__gpu_loop_group + 3); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + __gpu_bc_i = (__gpu_loop_group + 4); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + __gpu_bc_i = (__gpu_loop_group + 5); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + __gpu_bc_i = (__gpu_loop_group + 6); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + __gpu_bc_i = (__gpu_loop_group + 7); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + __gpu_bc_i = (__gpu_loop_group + 8); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + __gpu_bc_i = (__gpu_loop_group + 9); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + __gpu_bc_i = (__gpu_loop_group + 10); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + __gpu_bc_i = (__gpu_loop_group + 11); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + __gpu_bc_i = (__gpu_loop_group + 12); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + __gpu_bc_i = (__gpu_loop_group + 13); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + __gpu_bc_i = (__gpu_loop_group + 14); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + __gpu_bc_i = (__gpu_loop_group + 15); + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + } + for (__gpu_bc_i = __gpu_loop_group; __gpu_bc_i <= __gpu_loop_end; __gpu_bc_i++) { + t[((int)(__gpu_bc_i) - (1))] = (x[((int)(j) - (1))] + 4.10000000000000000e+01); + } + } + g[((int)(j) - (1))] = t[((int)(1) - (1))]; +} + +struct __ScalarArgs___lfortran_gpu_kernel_1 { + int __loop_end_0; +}; + +kernel void __lfortran_gpu_kernel_1( + device float* g [[buffer(0)]], + device float* u [[buffer(1)]], + device float* x [[buffer(2)]], + constant __ScalarArgs___lfortran_gpu_kernel_1& __scalar_args [[buffer(3)]], + uint __thread_id [[thread_position_in_grid]]) +{ + int __loop_end_0 = __scalar_args.__loop_end_0; + int __flat_idx; + int j; + int k; + const int n = 8; + if ((((0 * 0) + __thread_id) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { + return; + } + __flat_idx = ((0 * 0) + __thread_id); + j = (__flat_idx + 1); + k = 1; + u[((int)(k) - (1))] = 1.00000000000000000e+00; + u[((int)(((k + 1) - 1)) - (1))] = 1.00000000000000000e+00; + g[((int)(j) - (1))] = ((u[((int)(1) - (1))] + u[((int)(2) - (1))]) + x[((int)(j) - (1))]); +} + diff --git a/tests/reference/gpu_metal_kernel-gpu_metal_480-8fa07de.json b/tests/reference/gpu_metal_kernel-gpu_metal_480-8fa07de.json index 14dfdc200e2..b8a300e1efa 100644 --- a/tests/reference/gpu_metal_kernel-gpu_metal_480-8fa07de.json +++ b/tests/reference/gpu_metal_kernel-gpu_metal_480-8fa07de.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "gpu_metal_kernel-gpu_metal_480-8fa07de.stdout", - "stdout_hash": "369906b53d6a2eb1cfd19f43b7c0b92fe5a6ad372a5023c4a9cf72f7", + "stdout_hash": "abb92a36e281fa01de65585e394c49e1252243bb43c6ab32bcb28004", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/gpu_metal_kernel-gpu_metal_480-8fa07de.stdout b/tests/reference/gpu_metal_kernel-gpu_metal_480-8fa07de.stdout index 734b11f29bc..ae2189bf37e 100644 --- a/tests/reference/gpu_metal_kernel-gpu_metal_480-8fa07de.stdout +++ b/tests/reference/gpu_metal_kernel-gpu_metal_480-8fa07de.stdout @@ -27,7 +27,6 @@ kernel void __lfortran_gpu_kernel_0( uint __thread_id = __gpu_grid_thread / (uint)__gpu_lanes; int __gpu_lane = (int)(__gpu_grid_thread % (uint)__gpu_lanes); int __flat_idx; - const int count = 65; int i; if ((((0 * 0) + __thread_id) >= (((__loop_end_0 >= 1)) ? (((__loop_end_0 - 1) + 1)) : (0)))) { return; diff --git a/tests/reference/gpu_offload_cuda-gpu_decline_17-d2b52ed.json b/tests/reference/gpu_offload_cuda-gpu_decline_17-d2b52ed.json new file mode 100644 index 00000000000..662a9bc916b --- /dev/null +++ b/tests/reference/gpu_offload_cuda-gpu_decline_17-d2b52ed.json @@ -0,0 +1,13 @@ +{ + "basename": "gpu_offload_cuda-gpu_decline_17-d2b52ed", + "cmd": "lfortran --no-color --gpu=cuda -c {infile} -o {outfile}", + "infile": "tests/../integration_tests/gpu_decline_17.f90", + "infile_hash": "449f6e105a148238e88806e7bc3dfadf55cf008fd2851126c60bf278", + "outfile": null, + "outfile_hash": null, + "stdout": null, + "stdout_hash": null, + "stderr": "gpu_offload_cuda-gpu_decline_17-d2b52ed.stderr", + "stderr_hash": "b5d19fc7271b5940c4c49bf848944d0942e1be6951f7cdcfe4d97752", + "returncode": 5 +} \ No newline at end of file diff --git a/tests/reference/gpu_offload_cuda-gpu_decline_17-d2b52ed.stderr b/tests/reference/gpu_offload_cuda-gpu_decline_17-d2b52ed.stderr new file mode 100644 index 00000000000..0d55abec36e --- /dev/null +++ b/tests/reference/gpu_offload_cuda-gpu_decline_17-d2b52ed.stderr @@ -0,0 +1,9 @@ +ASR pass error: parallel loop cannot be offloaded to the GPU yet: array 't' of local locality is of type type(pair), which a gpu thread cannot hold a copy of + --> tests/../integration_tests/gpu_decline_17.f90:18:1 - 22:6 + | +18 | do concurrent (j = 1:n) local(t) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^... +... + | +22 | end do + | ...^^^^^^ array 't' of local locality is of type type(pair), which a gpu thread cannot hold a copy of diff --git a/tests/reference/gpu_offload_cuda-gpu_decline_18-b238281.json b/tests/reference/gpu_offload_cuda-gpu_decline_18-b238281.json new file mode 100644 index 00000000000..9b47e45b747 --- /dev/null +++ b/tests/reference/gpu_offload_cuda-gpu_decline_18-b238281.json @@ -0,0 +1,13 @@ +{ + "basename": "gpu_offload_cuda-gpu_decline_18-b238281", + "cmd": "lfortran --no-color --gpu=cuda -c {infile} -o {outfile}", + "infile": "tests/../integration_tests/gpu_decline_18.f90", + "infile_hash": "79322cd6dd050a54f47f3e272a4a42af10071a8b6f0e4ba769d6f670", + "outfile": null, + "outfile_hash": null, + "stdout": null, + "stdout_hash": null, + "stderr": "gpu_offload_cuda-gpu_decline_18-b238281.stderr", + "stderr_hash": "ada0cae395ad3a0f5fd1125c318cda785a982bb5deffccb9a649cfd4", + "returncode": 5 +} \ No newline at end of file diff --git a/tests/reference/gpu_offload_cuda-gpu_decline_18-b238281.stderr b/tests/reference/gpu_offload_cuda-gpu_decline_18-b238281.stderr new file mode 100644 index 00000000000..882f615f09a --- /dev/null +++ b/tests/reference/gpu_offload_cuda-gpu_decline_18-b238281.stderr @@ -0,0 +1,9 @@ +ASR pass error: parallel loop cannot be offloaded to the GPU yet: array 't' of local locality is named by an associate construct around the loop + --> tests/../integration_tests/gpu_decline_18.f90:16:5 - 20:10 + | +16 | do concurrent (j = 1:n) local(t) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^... +... + | +20 | end do + | ...^^^^^^^^^^ array 't' of local locality is named by an associate construct around the loop diff --git a/tests/reference/gpu_offload_cuda-gpu_decline_19-13fd5d9.json b/tests/reference/gpu_offload_cuda-gpu_decline_19-13fd5d9.json new file mode 100644 index 00000000000..cfe0d463435 --- /dev/null +++ b/tests/reference/gpu_offload_cuda-gpu_decline_19-13fd5d9.json @@ -0,0 +1,13 @@ +{ + "basename": "gpu_offload_cuda-gpu_decline_19-13fd5d9", + "cmd": "lfortran --no-color --gpu=cuda -c {infile} -o {outfile}", + "infile": "tests/../integration_tests/gpu_decline_19.f90", + "infile_hash": "76dbad05e8a1315e8b8a736838be156a1e4ca8887313529a3702d77b", + "outfile": null, + "outfile_hash": null, + "stdout": null, + "stdout_hash": null, + "stderr": "gpu_offload_cuda-gpu_decline_19-13fd5d9.stderr", + "stderr_hash": "c94e7dd2270200de708e79072c4654292d4356b1e7fcf664ef0d09a9", + "returncode": 5 +} \ No newline at end of file diff --git a/tests/reference/gpu_offload_cuda-gpu_decline_19-13fd5d9.stderr b/tests/reference/gpu_offload_cuda-gpu_decline_19-13fd5d9.stderr new file mode 100644 index 00000000000..3abb8597a53 --- /dev/null +++ b/tests/reference/gpu_offload_cuda-gpu_decline_19-13fd5d9.stderr @@ -0,0 +1,9 @@ +ASR pass error: parallel loop cannot be offloaded to the GPU yet: array 't' of local locality cannot be given a copy per gpu thread: the loop body has an associate construct the gpu kernel cannot inline + --> tests/../integration_tests/gpu_decline_19.f90:14:1 - 22:6 + | +14 | do concurrent (j = 1:n) local(t) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^... +... + | +22 | end do + | ...^^^^^^ array 't' of local locality cannot be given a copy per gpu thread: the loop body has an associate construct the gpu kernel cannot inline diff --git a/tests/tests.toml b/tests/tests.toml index 4b4f564de61..e1bb06ac407 100644 --- a/tests/tests.toml +++ b/tests/tests.toml @@ -4596,6 +4596,18 @@ gpu_offload_cuda = true filename = "../integration_tests/gpu_decline_16.f90" gpu_offload_cuda = true +[[test]] +filename = "../integration_tests/gpu_decline_17.f90" +gpu_offload_cuda = true + +[[test]] +filename = "../integration_tests/gpu_decline_18.f90" +gpu_offload_cuda = true + +[[test]] +filename = "../integration_tests/gpu_decline_19.f90" +gpu_offload_cuda = true + [[test]] filename = "gpu_decline_impure_condition.f90" gpu_offload_cuda = true @@ -4846,6 +4858,21 @@ filename = "../integration_tests/gpu_kernel_source_13.f90" gpu_metal_kernel = true gpu_cuda_kernel = true +[[test]] +filename = "../integration_tests/gpu_kernel_source_14.f90" +gpu_metal_kernel = true +gpu_cuda_kernel = true + +[[test]] +filename = "../integration_tests/gpu_kernel_source_16.f90" +gpu_metal_kernel = true +gpu_cuda_kernel = true + +[[test]] +filename = "../integration_tests/gpu_kernel_source_15.f90" +gpu_cuda_kernel = true +gpu_metal_kernel = true + [[test]] filename = "errors/array_bounds_check_01.f90" run = true