diff --git a/.cookiecutterrc b/.cookiecutterrc index 36b24ad..ad60375 100644 --- a/.cookiecutterrc +++ b/.cookiecutterrc @@ -17,16 +17,16 @@ default_context: - _output_dir: '/home/iavarone/repos' + _output_dir: '/home/lmoyasans/repos' _template: 'gh:ITISFoundation/cookiecutter-osparc-service' author_affiliation: "IT'IS Foundation" - author_email: 'iavarone@itis.swiss' - author_name: 'Elisabetta Iavarone' - contact_email: 'iavarone@itis.swiss' + author_email: 'moyasans@itis.swiss' + author_name: 'Lucia Moya-Sans' + contact_email: 'moyasans@itis.swiss' default_docker_registry: 'itisfoundation' docker_base: 'custom:special-image' git_repo: 'github' - git_username: 'elisabettai' + git_username: 'lmoyasans' number_of_inputs: '1' number_of_outputs: '1' project_name: 'k-Wave' @@ -35,4 +35,4 @@ default_context: project_slug: 'k-wave' project_type: 'computational' release_date: '2023' - version: '1.0.0' + version: '2.0.0' diff --git a/.github/dockerhub_login.bash b/.github/dockerhub_login.bash deleted file mode 100755 index 29972d7..0000000 --- a/.github/dockerhub_login.bash +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash -# http://redsymbol.net/articles/unofficial-bash-strict-mode/ -set -euo pipefail -IFS=$'\n\t' - -# check needed variables are defined -if [ ! -v DOCKER_USERNAME ] ||\ - [ ! -v DOCKER_PASSWORD ] ||\ - [ ! -v DOCKER_REGISTRY ]; then - echo "## ERROR: Please define the environs (DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY) in your CI settings!" - exit 1 -fi - -# check script needed variables -if [ ! -v OWNER ]; then - echo "## ERROR: incorrect usage of CI. OWNER (e.g. dockerhub organization like itisfoundation or user private name) not defined!" - exit 1 -fi - -# only upstream is allowed to push to itisfoundation repo -if [ "${OWNER,,}" != "itisfoundation" ] &&\ - { [ ! -v DOCKER_REGISTRY ] || [ -z "${DOCKER_REGISTRY}" ] || [ "$DOCKER_REGISTRY" = "itisfoundation" ]; }; then - echo "## ERROR: it is not allowed to push to the main dockerhub repository from a fork!" - echo "## Please adapt your CI-defined environs (DOCKER_USERNAME, DOCKER_PASSWORD, DOCKER_REGISTRY)" - exit 1 -fi - -# these variable must be available securely from the CI -echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin - -echo "logged into dockerhub successfully, ready to push" -exit 0 diff --git a/.github/show_system_versions.bash b/.github/show_system_versions.bash deleted file mode 100755 index c2a3b86..0000000 --- a/.github/show_system_versions.bash +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -# http://redsymbol.net/articles/unofficial-bash-strict-mode/ -set -euo pipefail -IFS=$'\n\t' - -echo "------------------------------ environs -----------------------------------" -env - -echo "------------------------------ uname -----------------------------------" -uname -a -lsb_release -a - -echo "------------------------------ python -----------------------------------" -if command -v python; then - python --version -fi - -echo "------------------------------ python3 -----------------------------------" -if command -v python3; then - python3 --version -fi - -echo "------------------------------ docker -----------------------------------" -if command -v docker; then - docker version -fi - -echo "------------------------------ docker-compose -----------------------------------" -if command -v docker-compose; then - docker-compose version -fi diff --git a/.github/workflows/build-test-publish.yml b/.github/workflows/build-test-publish.yml index 5872557..1401e07 100644 --- a/.github/workflows/build-test-publish.yml +++ b/.github/workflows/build-test-publish.yml @@ -1,58 +1,36 @@ -name: Github-CI Push/PR k-wave +name: Build and check image on: + # Run the workflow for pushes to the main branch push: + branches: + - main + + # Run the workflow for pull requests (from forks or within the repo) pull_request: + types: + - opened + - synchronize + - reopened -env: - # secrets can be set in settings/secrets on github - DOCKER_REGISTRY: ${{ secrets.DOCKER_REGISTRY }} - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - KWAVE_LOGIN: ${{ secrets.KWAVE_LOGIN }} - KWAVE_PASSWORD: ${{ secrets.KWAVE_PASSWORD }} jobs: - build: - name: building k-wave - runs-on: ${{ matrix.os }} - strategy: - matrix: - python: [3.9] - os: [ubuntu-22.04] - fail-fast: false + verify-image-build: + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: setup python environment - uses: actions/setup-python@v4 + - name: Checkout repo content + uses: actions/checkout@v6 + + - name: ooil version + uses: docker://itisfoundation/ci-service-integration-library:v2.2.8 + with: + args: ooil --version + - name: Assemble docker compose spec + uses: docker://itisfoundation/ci-service-integration-library:v2.2.8 + with: + args: ooil compose + - name: Build image + uses: docker://itisfoundation/ci-service-integration-library:v2.2.8 with: - python-version: ${{ matrix.python }} - - name: show versions - run: ./.github/show_system_versions.bash - - name: set owner variable - run: echo "OWNER=${GITHUB_REPOSITORY%/*}" >> $GITHUB_ENV - - name: set docker image tag - if: github.ref != 'refs/heads/main' - run: echo "DOCKER_IMAGE_TAG=${GITHUB_REF##*/}" >> $GITHUB_ENV - - name: get current image if available - run: make pull-latest || true - - name: build - run: | - make VERSION - make build - make info-build - - if: github.event_name == 'push' && github.ref == 'refs/heads/main' - name: Event is push to main - run: | - ./.github/dockerhub_login.bash - DOCKER_IMAGE_TAG=$(< VERSION) - echo "Docker image tag is ${DOCKER_IMAGE_TAG}" - make tag-version - make push - - if: github.event_name == 'push' && ${{ github.event.pull_request.merged }} - name: Event is PR is merged - run: | - ./.github/dockerhub_login.bash - DOCKER_IMAGE_TAG=$(< VERSION) - echo "Docker image tag is ${DOCKER_IMAGE_TAG}" - make tag-version - make push + args: docker compose build + - name: test k-wave + run: make run-local diff --git a/.gitignore b/.gitignore index e692c51..0a48a80 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ pytest_*.xml !.dockerignore # git ignore !.gitignore +docker-compose.yml +validation/ \ No newline at end of file diff --git a/.osparc/bin/ooil.bash b/.osparc/bin/ooil.bash deleted file mode 100755 index 62b6cdf..0000000 --- a/.osparc/bin/ooil.bash +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -# http://redsymbol.net/articles/unofficial-bash-strict-mode/ - -set -o errexit -set -o nounset -set -o pipefail -IFS=$'\n\t' - -IMAGE_NAME="itisfoundation/service-integration:${OOIL_IMAGE_TAG:-master-github-latest}" -WORKDIR="$(pwd)" - -# -# NOTE: with --interactive --tty the command below will -# produce colors in the outputs. The problem is that -# . ooil.bash >VERSION will insert special color codes -# . in the VERSION file which make it unusable as a variable -# . when cat VERSION !! -# - -run() { - docker run \ - --rm \ - --pull=always\ - --volume="/etc/group:/etc/group:ro" \ - --volume="/etc/passwd:/etc/passwd:ro" \ - --user="$(id --user "$USER")":"$(id --group "$USER")" \ - --volume "$WORKDIR":/src \ - --workdir=/src \ - "$IMAGE_NAME" \ - "$@" -} - -# ---------------------------------------------------------------------- -# MAIN -# -# USAGE -# ./scripts/ooil.bash --help - -run "$@" -# ---------------------------------------------------------------------- diff --git a/.osparc/docker-compose.overwrite.yml b/.osparc/docker-compose.overwrite.yml index 5deef10..d49cd0f 100644 --- a/.osparc/docker-compose.overwrite.yml +++ b/.osparc/docker-compose.overwrite.yml @@ -4,6 +4,3 @@ services: build: dockerfile: docker/custom/Dockerfile target: production - args: - - KWAVE_LOGIN - - KWAVE_PASSWORD diff --git a/.osparc/metadata.yml b/.osparc/metadata.yml index 9eaaaa3..fc2620f 100644 --- a/.osparc/metadata.yml +++ b/.osparc/metadata.yml @@ -2,14 +2,17 @@ name: k-Wave key: simcore/services/comp/k-wave type: computational integration-version: 1.0.0 -version: 1.0.0 -description: k-Wave is a MATLAB toolbox for the time-domain simulation of acoustic wave fields. This service uses the kspaceFirstOrder-CUDA function to run 3D time-domain simulation of wave propagation on a GPU using C++ CUDA code (k-Wave version 1.3).

Have an issue? Create one at https://github.com/ITISFoundation/k-wave/issues -contact: iavarone@itis.swiss +version: 2.0.0 +description: k-Wave is a MATLAB toolbox for the time-domain simulation of acoustic wave fields. This service uses the kspaceFirstOrder-CUDA function to run 3D time-domain simulation of wave propagation on a GPU using C++ CUDA code. Built with CUDA 12.2; supports Turing (sm_75) through Ada Lovelace (sm_89, RTX 4070) and Hopper (sm_90).

Have an issue? Create one at https://github.com/ITISFoundation/k-wave/issues +contact: moyasans@itis.swiss thumbnail: https://pbs.twimg.com/media/ER4wiXEWkAAY-GD.jpg authors: - name: Elisabetta Iavarone email: iavarone@itis.swiss affiliation: IT'IS Foundation + - name: Lucia Moya-Sans + email: moyasans@itis.swiss + affiliation: IT'IS Foundation inputs: input_1: displayOrder: 1 diff --git a/Makefile b/Makefile index 63f8e52..f73e4e9 100644 --- a/Makefile +++ b/Makefile @@ -1,181 +1,81 @@ -# -# Author: Elisabetta Iavarone +# minimalistic utility to test and develop locally SHELL = /bin/sh .DEFAULT_GOAL := help -export VCS_URL := $(shell git config --get remote.origin.url 2> /dev/null || echo unversioned repo) -export VCS_REF := $(shell git rev-parse --short HEAD 2> /dev/null || echo unversioned repo) -export VCS_STATUS := $(if $(shell git status -s 2> /dev/null || echo unversioned repo),'modified/untracked','clean') -export BUILD_DATE := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ") - -export DOCKER_REGISTRY ?= itisfoundation -export DOCKER_IMAGE_NAME ?= k-wave -export DOCKER_IMAGE_TAG ?= $(shell cat VERSION 2> /dev/null || echo undefined) - -export COMPOSE_INPUT_DIR := ./validation/input -export COMPOSE_OUTPUT_DIR := .tmp/output - -OSPARC_DIR:=$(CURDIR)/.osparc - -APP_NAME := k-wave - - - - -# INTEGRATION ----------------------------------------------------------------- -METADATA := .osparc/metadata.yml - - -.PHONY: VERSION -VERSION: $(METADATA) ## generates VERSION from metadata - # updating $@ from $< - @$(OSPARC_DIR)/bin/ooil.bash get-version --metadata-file $< > $@ - -service.cli/run: $(METADATA) ## generates run from metadata - # Updates adapter script from metadata in $< - @$(OSPARC_DIR)/bin/ooil.bash run-creator --metadata $< --runscript $@ - -docker-compose.yml: $(METADATA) ## generates docker-compose - # Injects metadata from $< as labels - @$(OSPARC_DIR)/bin/ooil.bash compose --to-spec-file $@ --metadata $< - - - -# BUILD ----------------------------------------------------------------- - -define _docker_compose_build -export DOCKER_BUILD_TARGET=$(if $(findstring -devel,$@),development,$(if $(findstring -cache,$@),cache,production)); \ - docker compose -f docker-compose.yml build $(if $(findstring -nc,$@),--no-cache,); +export IMAGE_NAME=k-wave +export IMAGE_TAG=2.0.0 + +# PYTHON ENVIRON --------------------------------------------------------------- +.PHONY: devenv +.venv: + @python3 --version + python3 -m venv $@ + # upgrading package managers + $@/bin/pip install --upgrade uv + +devenv: .venv ## create a python virtual environment with tools to dev, run and tests + # installing extra tools + @$ /dev/null && echo "image version is valid") -version_exists = $(shell DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect $(DOCKER_REGISTRY)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG) > /dev/null && echo "image already exists on $(DOCKER_REGISTRY)") -push push-force: ## pushes (resp. force) services to the registry if service not available in registry. - @$(if $(findstring force,$@),,\ - $(if $(call version_valid),$(info version is valid), $(error $(DOCKER_IMAGE_TAG) is not a valid version (major>=1)))\ - $(if $(call version_exists),$(error $(DOCKER_REGISTRY)/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG) already exists on $(DOCKER_REGISTRY)), $(info no version found on $(DOCKER_REGISTRY)))\ - ) - @$(MAKE) push-version; - @$(MAKE) push-latest; +# To test built service locally ------------------------------------------------ +.PHONY: run-local +run-local: ## runs image with local configuration + IMAGE_TO_RUN=${IMAGE_NAME} \ + TAG_TO_RUN=${IMAGE_TAG} \ + docker compose --file docker-compose-local.yml up .PHONY: publish-local publish-local: ## push to local throw away registry to test integration - docker tag simcore/services/comp/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} registry:5000/simcore/services/comp/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG) - docker push registry:5000/simcore/services/comp/$(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG) + docker tag simcore/services/comp/${IMAGE_NAME}:${IMAGE_TAG} registry:5000/simcore/services/comp/${IMAGE_NAME}:${IMAGE_TAG} + docker push registry:5000/simcore/services/comp/${IMAGE_NAME}:${IMAGE_TAG} @curl registry:5000/v2/_catalog | jq - -push-latest push-version: ## publish service to registry with latest/version tag - # pushing '$(DOCKER_REGISTRY)/$(DOCKER_IMAGE_NAME):$(if $(findstring version,$@),$(DOCKER_IMAGE_TAG),latest)'... - @$(MAKE) tag-$(subst push-,,$@) - @docker push $(DOCKER_REGISTRY)/$(DOCKER_IMAGE_NAME):$(if $(findstring version,$@),$(DOCKER_IMAGE_TAG),latest) - # pushed '$(DOCKER_REGISTRY)/$(DOCKER_IMAGE_NAME):$(if $(findstring version,$@),$(DOCKER_IMAGE_TAG),latest)' - -pull-latest pull-version: ## pull service from registry - @docker pull $(DOCKER_REGISTRY)/$(DOCKER_IMAGE_NAME):$(if $(findstring version,$@),$(DOCKER_IMAGE_TAG),latest) - - - - -# COOCKIECUTTER ----------------------------------------------------------------- - -.PHONY: replay -replay: .cookiecutterrc ## re-applies cookiecutter - # Replaying gh:ITISFoundation/cookiecutter-osparc-service ... - @cookiecutter --no-input --overwrite-if-exists \ - --config-file=$< \ - --output-dir="$(abspath $(CURDIR)/..)" \ - "gh:ITISFoundation/cookiecutter-osparc-service" - - - -.PHONY: info -info: ## general info - # env vars: version control - @echo " VCS_URL : $(VCS_URL)" - @echo " VCS_REF : $(VCS_REF)" - @echo " VCS_STATUS : $(VCS_STATUS)" - # env vars: docker - @echo " DOCKER_REGISTRY : $(DOCKER_REGISTRY)" - @echo " DOCKER_IMAGE_NAME : $(DOCKER_IMAGE_NAME)" - @echo " DOCKER_IMAGE_TAG : $(DOCKER_IMAGE_TAG)" - @echo " COMPOSE_INPUT_DIR : $(COMPOSE_INPUT_DIR)" - @echo " COMPOSE_OUTPUT_DIR : $(COMPOSE_OUTPUT_DIR)" - @echo " BUILD_DATE : $(BUILD_DATE)" - # exe: recommended dev tools - @echo ' git : $(shell git --version 2>/dev/null || echo not found)' - @echo ' make : $(shell make --version 2>&1 | head -n 1)' - @echo ' jq : $(shell jq --version 2>/dev/null || echo not found z)' - @echo ' awk : $(shell awk -W version 2>&1 | head -n 1 2>/dev/null || echo not found)' - @echo ' python : $(shell python3 --version 2>/dev/null || echo not found )' - @echo ' docker : $(shell docker --version)' - @echo ' docker buildx : $(shell docker buildx version)' - @echo ' docker-compose : $(shell docker-compose --version)' - # exe: integration tools - @echo ' ooil version : $(shell $(OSPARC_DIR)/bin/ooil.bash --version)' - - - -# MISC ----------------------------------------------------------------- .PHONY: help help: ## this colorful help @echo "Recipes for '$(notdir $(CURDIR))':" @echo "" - @awk --posix 'BEGIN {FS = ":.*?## "} /^[[:alpha:][:space:]_-]+:.*?## / {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) + @awk 'BEGIN {FS = ":.*?## "} /^[[:alpha:][:space:]_-]+:.*?## / {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) @echo "" - - -.PHONY: clean -git_clean_args = -dxf --exclude=.vscode/ - -clean: ## cleans all unversioned files in project and temp files create by this makefile - # Cleaning unversioned - @git clean -n $(git_clean_args) - @echo -n "Are you sure? [y/N] " && read ans && [ $${ans:-N} = y ] - @echo -n "$(shell whoami), are you REALLY sure? [y/N] " && read ans && [ $${ans:-N} = y ] - @git clean $(git_clean_args) diff --git a/README.md b/README.md index 00b910e..429db90 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,6 @@ $ make help $ make build $ make publish-local ``` -**Note**: to build the image, you need an account [to download k-Wave](http://www.k-wave.org/download.php). In version 1.0.0 the pre-compiled executables are used. ### How to test Use as input the file `validation/input/input.h5`. Running the service should generate an `output.h5` file. diff --git a/docker-compose-local.yml b/docker-compose-local.yml new file mode 100644 index 0000000..3ba5661 --- /dev/null +++ b/docker-compose-local.yml @@ -0,0 +1,9 @@ +services: + k-wave: + image: simcore/services/comp/${IMAGE_TO_RUN}:${TAG_TO_RUN} + environment: + - INPUT_FOLDER=/tmp/inputs + - OUTPUT_FOLDER=/tmp/outputs + volumes: + - ${PWD}/validation/input:/tmp/inputs + - ${PWD}/validation/output:/tmp/outputs diff --git a/docker/custom/Dockerfile b/docker/custom/Dockerfile index 7d600ad..f732811 100644 --- a/docker/custom/Dockerfile +++ b/docker/custom/Dockerfile @@ -1,96 +1,115 @@ -FROM nvidia/cudagl:11.2.2-runtime-ubuntu20.04 as base -# -# USAGE: -# cd services/k-wave -# docker build -f Dockerfile -t k-wave:prod --target production ../../ -# docker run k-wave:prod -# +# v2.0.0 builds kspaceFirstOrder-CUDA from source +# (https://github.com/klepo/k-Wave-Fluid-CUDA) using CUDA 12.2 and targets +# sm_75 (Turing) through sm_90 (Hopper), covering all current consumer and +# data-centre NVIDIA GPUs. -LABEL maintainer=elisabettai +# ======================== Build stage ======================== +FROM nvidia/cuda:12.2.2-devel-ubuntu22.04 AS build -# simcore-user uid=8004(${SC_USER_NAME}) gid=8004(${SC_USER_NAME}) groups=8004(${SC_USER_NAME}) -ENV SC_USER_ID 8004 -ENV SC_USER_NAME scu -RUN adduser --uid ${SC_USER_ID} --disabled-password --gecos "" --shell /bin/sh --home /home/${SC_USER_NAME} ${SC_USER_NAME} - -RUN apt-get update \ - && apt-get -y install --no-install-recommends \ - jq \ - && rm --recursive --force /var/lib/apt/lists/* - -# -------------------------- Build stage ------------------- -# Installs build/package management tools and third party dependencies -# -# + /build WORKDIR -# +LABEL maintainer=lmoyasans -FROM base as build +ENV SC_BUILD_TARGET=build -ENV SC_BUILD_TARGET build +ENV KWAVE_COMMIT=44ca4ed1fce2319c1558ec5ba3a165d3d44a5da1 -ARG KWAVE_PASSWORD -ARG KWAVE_LOGIN -# ------------------------------------------------------------------------------------ -# build dependencies shall be installed RUN apt-get update \ && apt-get -y install --no-install-recommends \ - unzip \ - gcc \ - curl \ -&& rm -rf /var/lib/apt/lists/* - -# ------------------------------------------------------------------------------------ -# Download binaries (get authentication cookie to login to http://www.k-wave.org/download.php and download the file with the cookie) -# Note, you need to have a valid login and export credentials as env. variables - -WORKDIR /build + git \ + make \ + g++ \ + libhdf5-dev \ + zlib1g-dev \ + libaec-dev \ + && rm -rf /var/lib/apt/lists/* +# Create the HDF5 prefix layout expected by the k-Wave Makefile: +# $(HDF5_DIR)/include and $(HDF5_DIR)/lib +# Ubuntu 22.04 puts the serial-variant files in non-standard sub-directories. +RUN mkdir -p /opt/hdf5 \ + && ln -s /usr/include/hdf5/serial /opt/hdf5/include \ + && ln -s /usr/lib/x86_64-linux-gnu/hdf5/serial /opt/hdf5/lib -RUN curl --cookie-jar cookie.txt --form password=$KWAVE_PASSWORD --form user_login=$KWAVE_LOGIN http://www.k-wave.org/forum/bb-login.php && \ - curl -L -b cookie.txt http://www.k-wave.org/getfile.php?id=117 -o kwave.zip && \ - unzip kwave.zip && \ - rm kwave.zip cookie.txt -# ------------------------------------------------------------------------------------ +# libaec-dev provides SZIP compatibility; ensure libsz.a is reachable. +RUN ls /usr/lib/x86_64-linux-gnu/libsz.a 2>/dev/null \ + || ln -s /usr/lib/x86_64-linux-gnu/libaec.a \ + /usr/lib/x86_64-linux-gnu/libsz.a +WORKDIR /build -# defines the output of the build -RUN mkdir --parents /build/bin -# copy src code: There's none for the moment -#COPY --chown=${SC_USER_NAME}:${SC_USER_NAME} src/k_wave src/k_wave -# ------------------------------------------------------------------------------------ -#TODO: -# uncomment and adapt if build steps are necessary. For now, we use the compiled executable -RUN cp -R /build/kspaceFirstOrder-CUDA /build/bin -# ------------------------------------------------------------------------------------ +# Clone the open-source k-Wave CUDA fluid solver (pinned to known-good commit). +RUN git clone https://github.com/klepo/k-Wave-Fluid-CUDA.git . \ + && git checkout ${KWAVE_COMMIT} -# --------------------------Production stage ------------------- -# Final cleanup up to reduce image size and startup setup -# Runs as ${SC_USER_NAME} (non-root user) +# Patch source to fix compilation issues in the feat_q_computing branch: # -# + /home/${SC_USER_NAME} $HOME = WORKDIR -# + k_wave [${SC_USER_NAME}:${SC_USER_NAME}] -# + docker [${SC_USER_NAME}:${SC_USER_NAME}] -# + service.cli [${SC_USER_NAME}:${SC_USER_NAME}] -# -FROM base as production +# 1. Case mismatch: sources include (all-caps) +# but the actual file is SolverCudaKernels.cuh — create a symlink. +# 2. KSpaceFirstOrderSolver.cpp uses std::ifstream (), strcmp (), +# sysconf/_SC_PHYS_PAGES/_SC_PAGE_SIZE (/), +# and _mm_malloc/_mm_free () without including the required headers. +# 3. IndexMatrix.cpp uses ceilf() without #include . +# 4. CompressHelper.cpp uses std::numeric_limits without #include . +RUN ln -s SolverCudaKernels.cuh KSpaceSolver/SolverCUDAKernels.cuh && \ + sed -i 's|^#include |#include \n#include \n#include \n#include \n#include |' \ + KSpaceSolver/KSpaceFirstOrderSolver.cpp && \ + sed -i '1s|^|#include \n|' MatrixClasses/IndexMatrix.cpp && \ + sed -i '1s|^|#include \n|' Compression/CompressHelper.cpp + +# Build with CUDA 12.2. +# SEMI linking: HDF5 + zlib + szip linked statically, cuFFT dynamically +# (avoids the static-cuFFT relocation bug noted in the upstream Makefile). +# CUDA_ARCH: cover Turing (sm_75) → Ada Lovelace (sm_89) → Hopper (sm_90). +# LIBS is passed on the command line to override the ifeq(LINKING,SEMI) block, +# since Ubuntu 22.04 places static libs in /usr/lib/x86_64-linux-gnu/ not /usr/lib/. +RUN make -f Makefiles/Release/Makefile -j"$(nproc)" \ + HDF5_DIR=/opt/hdf5 \ + CUDA_DIR=/usr/local/cuda \ + LINKING=SEMI \ + LIBS="/opt/hdf5/lib/libhdf5_hl.a \ + /opt/hdf5/lib/libhdf5.a \ + /usr/lib/x86_64-linux-gnu/libz.a \ + /usr/lib/x86_64-linux-gnu/libsz.a \ + /usr/lib/x86_64-linux-gnu/libaec.a \ + -lcufft -ldl" \ + CUDA_ARCH="--generate-code arch=compute_75,code=sm_75 \ + --generate-code arch=compute_80,code=sm_80 \ + --generate-code arch=compute_86,code=sm_86 \ + --generate-code arch=compute_89,code=sm_89 \ + --generate-code arch=compute_90,code=sm_90" + +RUN mkdir -p /build/bin \ + && cp kspaceFirstOrder-CUDA /build/bin/ + +# ======================== Production stage ======================== +# simcore-user uid=8004(${SC_USER_NAME}) gid=8004(${SC_USER_NAME}) groups=8004(${SC_USER_NAME}) +FROM nvidia/cuda:12.2.2-runtime-ubuntu22.04 AS production -ENV SC_BUILD_TARGET production -ENV SC_BOOT_MODE production +ENV SC_USER_ID=8004 \ + SC_USER_NAME=scu +RUN adduser --uid ${SC_USER_ID} --disabled-password --gecos "" \ + --shell /bin/sh --home /home/${SC_USER_NAME} ${SC_USER_NAME} + +ENV SC_BUILD_TARGET=production \ + SC_BOOT_MODE=production ENV INPUT_FOLDER="/input" \ OUTPUT_FOLDER="/output" +# GPU access: all modern NVIDIA GPUs are visible. +# Ada Lovelace (sm_89) and Hopper (sm_90) are fully supported. +# Requires CUDA-capable driver ≥ 525 (ships CUDA 12.0 user-space ABI). +ENV NVIDIA_VISIBLE_DEVICES=all \ + NVIDIA_DRIVER_CAPABILITIES=compute,utility \ + NVIDIA_REQUIRE_CUDA="cuda>=12.0 driver>=525" WORKDIR /home/${SC_USER_NAME} -# ------------------------------------------------------------------------------------ -# uncomment and adapt to install runtime dependencies RUN apt-get update \ && apt-get -y install --no-install-recommends \ + jq \ libgomp1 \ && rm -rf /var/lib/apt/lists/* -# ------------------------------------------------------------------------------------ # copy docker bootup scripts COPY --chown=${SC_USER_NAME}:${SC_USER_NAME} docker/custom/*.sh docker/ @@ -99,9 +118,9 @@ COPY --chown=${SC_USER_NAME}:${SC_USER_NAME} service.cli/ service.cli/ # necessary to be able to call run directly without sh in front ENV PATH="/home/${SC_USER_NAME}/service.cli:${PATH}" -# copy binaries from build +# copy binary from build stage COPY --from=build --chown=${SC_USER_NAME}:${SC_USER_NAME} /build/bin k_wave RUN chmod +x k_wave/* -ENTRYPOINT [ "/bin/sh", "docker/entrypoint.sh", "/bin/sh", "-c" ] +ENTRYPOINT [ "/bin/sh", "docker/entrypoint.sh" ] CMD ["run"] diff --git a/service.cli/execute.sh b/service.cli/run similarity index 70% rename from service.cli/execute.sh rename to service.cli/run index 12ef986..a877ddd 100755 --- a/service.cli/execute.sh +++ b/service.cli/run @@ -14,6 +14,29 @@ echo # ---------------------------------------------------------------- # This script shall be modified according to the needs in order to run the service +# Read inputs from inputs.json (written by the computational sidecar) +INPUTS_JSON="${INPUT_FOLDER}/inputs.json" +if [ -f "${INPUTS_JSON}" ]; then + echo "Reading inputs from ${INPUTS_JSON}..." + INPUT_2=$(jq -r '.input_2' "${INPUTS_JSON}") + INPUT_3=$(jq -r '.input_3' "${INPUTS_JSON}") + INPUT_4=$(jq -r '.input_4' "${INPUTS_JSON}") + INPUT_5=$(jq -r '.input_5' "${INPUTS_JSON}") + INPUT_6=$(jq -r '.input_6' "${INPUTS_JSON}") + INPUT_7=$(jq -r '.input_7' "${INPUTS_JSON}") + INPUT_8=$(jq -r '.input_8' "${INPUTS_JSON}") + INPUT_9=$(jq -r '.input_9' "${INPUTS_JSON}") + INPUT_10=$(jq -r '.input_10' "${INPUTS_JSON}") + INPUT_11=$(jq -r '.input_11' "${INPUTS_JSON}") + INPUT_12=$(jq -r '.input_12' "${INPUTS_JSON}") + INPUT_13=$(jq -r '.input_13' "${INPUTS_JSON}") + INPUT_14=$(jq -r '.input_14' "${INPUTS_JSON}") + INPUT_15=$(jq -r '.input_15' "${INPUTS_JSON}") + INPUT_16=$(jq -r '.input_16' "${INPUTS_JSON}") + INPUT_17=$(jq -r '.input_17' "${INPUTS_JSON}") + INPUT_18=$(jq -r '.input_18' "${INPUTS_JSON}") +fi + # From isolve: checking for resources limit env vars injected by osparc SIMCORE_NANO_CPUS_LIMIT="${SIMCORE_NANO_CPUS_LIMIT:-0}" echo "Setting/getting CPU limit gives this: ${SIMCORE_NANO_CPUS_LIMIT}" diff --git a/validation/output/.gitkeep b/validation/output/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/validation/output/outputs.json b/validation/output/outputs.json deleted file mode 100644 index 28ca0c6..0000000 --- a/validation/output/outputs.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "output_1":"some_stuff" -}