Skip to content

Add IPC shared memory example using the ipc.h API #451

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -437,8 +437,13 @@ install(FILES ${CMAKE_SOURCE_DIR}/LICENSE.TXT
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}/")

install(
FILES examples/basic/gpu_shared_memory.c examples/basic/utils_level_zero.h
examples/basic/basic.c examples/basic/ipc_level_zero.c
FILES examples/basic/gpu_shared_memory.c
examples/basic/utils_level_zero.h
examples/basic/basic.c
examples/basic/ipc_level_zero.c
examples/basic/ipc_shm_ipcapi.sh
examples/basic/ipc_shm_ipcapi_consumer.c
examples/basic/ipc_shm_ipcapi_producer.c
DESTINATION "${CMAKE_INSTALL_DOCDIR}/examples")

# Add the include directory and the headers target to the install.
Expand Down
34 changes: 34 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,37 @@ else()
"UMF_BUILD_LEVEL_ZERO_PROVIDER, UMF_BUILD_LIBUMF_POOL_DISJOINT and "
"UMF_ENABLE_POOL_TRACKING to be turned ON - skipping")
endif()

if(LINUX AND UMF_BUILD_LIBUMF_POOL_SCALABLE)
set(BASE_NAME ipc_shm_ipcapi)
set(EXAMPLE_NAME umf_example_${BASE_NAME})

foreach(loop_var IN ITEMS "producer" "consumer")
set(EX_NAME ${EXAMPLE_NAME}_${loop_var})
add_umf_executable(
NAME ${EX_NAME}
SRCS basic/${BASE_NAME}_${loop_var}.c
LIBS umf scalable_pool)

target_include_directories(
${EX_NAME} PRIVATE ${UMF_CMAKE_SOURCE_DIR}/src/utils
${UMF_CMAKE_SOURCE_DIR}/include)

target_link_directories(${EX_NAME} PRIVATE ${LIBHWLOC_LIBRARY_DIRS})
endforeach(loop_var)

file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/basic/${BASE_NAME}.sh
DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

add_test(
NAME ${EXAMPLE_NAME}
COMMAND ${BASE_NAME}.sh
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

set_tests_properties(${EXAMPLE_NAME} PROPERTIES LABELS "example")
else()
message(
STATUS
"IPC shared memory example with UMF pool API is supported on Linux only - skipping"
)
endif()
33 changes: 33 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,36 @@ and build this example Level Zero development package should be installed.
* Level Zero headers and libraries
* compatible GPU with installed driver
* set UMF_BUILD_GPU_EXAMPLES, UMF_BUILD_LIBUMF_POOL_DISJOINT, UMF_BUILD_LEVEL_ZERO_PROVIDER and UMF_ENABLE_POOL_TRACKING CMake configuration flags to ON

## IPC example with shared memory
This example also demonstrates how to use UMF IPC API. The example creates two
processes: a producer and a consumer that communicate in the following way
(the initial value N in the shared memory is quasi-random):
- Consumer starts
- Consumer creates a socket
- Consumer listens for incoming connections
- Producer starts
- Producer's shared memory contains a number: N
- Producer gets the IPC handle
- Producer creates a socket
- Producer connects to the consumer
- Consumer connects at IP 127.0.0.1 and a port to the producer
- Producer sends the size of the IPC handle to the consumer
- Consumer receives the size of the IPC handle
- Consumer sends the received size of the IPC handle as a confirmation back to the producer
- Producer receives the confirmation from the consumer and verifies if it is correct
- Producer sends the IPC handle to the consumer
- Consumer receives the IPC handle from the producer
- Consumer opens the IPC handle received from the producer
- Consumer reads the number from the producer's shared memory: N
- Consumer writes a new number directly to the producer's shared memory: N/2
- Consumer sends a response message to the producer
- Producer receives the response message from the consumer: "This is the consumer. I just wrote a new number directly into your shared memory!"
- Producer verifies if the consumer wrote the correct value (the old one / 2) to the producer's shared memory: N/2
- Consumer closes the IPC handle received from the producer
- Producer puts the IPC handle
- Consumer shuts down
- Producer shuts down

### Requirements
* set UMF_BUILD_LIBUMF_POOL_SCALABLE CMake configuration flag to ON
48 changes: 48 additions & 0 deletions examples/basic/ipc_shm_ipcapi.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#
# Copyright (C) 2024 Intel Corporation
#
# Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#

#!/bin/bash

# port should be a number from the range <1024, 65535>
PORT=$(( 1024 + ( $$ % ( 65535 - 1024 ))))

# The ipc_shm_ipcapi example requires using pidfd_getfd(2)
# to obtain a duplicate of another process's file descriptor.
# Permission to duplicate another process's file descriptor
# is governed by a ptrace access mode PTRACE_MODE_ATTACH_REALCREDS check (see ptrace(2))
# that can be changed using the /proc/sys/kernel/yama/ptrace_scope interface.
PTRACE_SCOPE_FILE="/proc/sys/kernel/yama/ptrace_scope"
VAL=0
if [ -f $PTRACE_SCOPE_FILE ]; then
PTRACE_SCOPE_VAL=$(cat $PTRACE_SCOPE_FILE)
if [ $PTRACE_SCOPE_VAL -ne $VAL ]; then
# check if sudo requires password
if ! timeout --kill-after=5s 3s sudo date; then
echo "ERROR: sudo requires password - cannot set ptrace_scope to 0"
exit 1
fi
echo "Setting ptrace_scope to 0 (classic ptrace permissions) ..."
echo "$ sudo bash -c \"echo $VAL > $PTRACE_SCOPE_FILE\""
sudo bash -c "echo $VAL > $PTRACE_SCOPE_FILE"
fi
PTRACE_SCOPE_VAL=$(cat $PTRACE_SCOPE_FILE)
if [ $PTRACE_SCOPE_VAL -ne $VAL ]; then
echo "SKIP: setting ptrace_scope to 0 (classic ptrace permissions) FAILED - skipping the test"
exit 0
fi
fi

UMF_LOG_VAL="level:debug;flush:debug;output:stderr;pid:yes"

echo "Starting ipc_shm_ipcapi CONSUMER on port $PORT ..."
UMF_LOG=$UMF_LOG_VAL ./umf_example_ipc_shm_ipcapi_consumer $PORT &

echo "Waiting 1 sec ..."
sleep 1

echo "Starting ipc_shm_ipcapi PRODUCER on port $PORT ..."
UMF_LOG=$UMF_LOG_VAL ./umf_example_ipc_shm_ipcapi_producer $PORT
Loading