Repository: oneapi-src/unified-memory-framework (language: python)

Issue:
Fix: remove incorrect assert in utils_align_ptr_up_size_down()
### Description

Remove incorrect assert in `utils_align_ptr_up_size_down()`.
A pointer is aligned, but a size is only adjusted to the new pointer.
The size does not have to be aligned.

### Checklist
<!--
Put an 'x' in the boxes that are checked.
Before checking all the boxes please mark the PR as draft.
-->

- [x] Code compiles without errors locally
- [x] All tests pass locally
- [x] CI workflows execute properly
<!-- If you have more tasks to do before merging this PR, simply add them here -->



Discussion / hints:

Fix patch:
diff --git a/.github/workflows/reusable_gpu.yml b/.github/workflows/reusable_gpu.yml
index 739aab9e1..913a0f0f1 100644
--- a/.github/workflows/reusable_gpu.yml
+++ b/.github/workflows/reusable_gpu.yml
@@ -129,5 +129,5 @@ jobs:
       - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
         if: ${{ matrix.build_type == 'Debug' && matrix.os == 'Ubuntu' }}
         with:
-          name: ${{env.COVERAGE_NAME}}-${{matrix.os}}-${{matrix.build_type}}-shared-${{matrix.shared_library}}
+          name: ${{env.COVERAGE_NAME}}-shared-${{matrix.shared_library}}
           path: ${{env.COVERAGE_DIR}}
diff --git a/.github/workflows/reusable_multi_numa.yml b/.github/workflows/reusable_multi_numa.yml
index 2ccb2d8f3..f65478984 100644
--- a/.github/workflows/reusable_multi_numa.yml
+++ b/.github/workflows/reusable_multi_numa.yml
@@ -69,7 +69,7 @@ jobs:
             --gtest_filter="-*checkModeLocal/*:*checkModePreferredEmptyNodeset/*:testNuma.checkModeInterleave"
 
       - name: Check coverage
-        if: matrix.os == 'ubuntu-22.04'
+        if: ${{ matrix.build_type == 'Debug' && matrix.os == 'ubuntu-22.04' }}
         working-directory: ${{env.BUILD_DIR}}
         run: |
           export COVERAGE_FILE_NAME=${{env.COVERAGE_NAME}}-${{matrix.os}}-shared-${{matrix.shared_library}}
@@ -79,7 +79,7 @@ jobs:
           mv ./$COVERAGE_FILE_NAME ${{env.COVERAGE_DIR}}
 
       - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
-        if: matrix.os == 'ubuntu-22.04'
+        if: ${{ matrix.build_type == 'Debug' && matrix.os == 'ubuntu-22.04' }}
         with:
-          name: ${{env.COVERAGE_NAME}}-${{matrix.os}}-${{matrix.build_type}}-shared-${{matrix.shared_library}}
+          name: ${{env.COVERAGE_NAME}}-${{matrix.os}}-shared-${{matrix.shared_library}}
           path: ${{env.COVERAGE_DIR}}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1e8ad7268..1d0890831 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -265,8 +265,8 @@ else()
                 ./configure --prefix=${hwloc_targ_BINARY_DIR}
                 --enable-static=yes --enable-shared=no --disable-libxml2
                 --disable-pci --disable-levelzero --disable-opencl
-                --disable-cuda --disable-nvml --disable-libudev CFLAGS=-fPIC
-                CXXFLAGS=-fPIC
+                --disable-cuda --disable-nvml --disable-libudev --disable-rsmi
+                CFLAGS=-fPIC CXXFLAGS=-fPIC
             WORKING_DIRECTORY ${hwloc_targ_SOURCE_DIR}
             OUTPUT ${hwloc_targ_SOURCE_DIR}/Makefile
             DEPENDS ${hwloc_targ_SOURCE_DIR}/configure)
diff --git a/ChangeLog b/ChangeLog
index 2b41d7d9b..ce5503350 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+Mon Dec 09 2024 Łukasz Stolarczuk <lukasz.stolarczuk@intel.com>
+
+	* Version 0.10.0
+
+	In this release we introduced updates in several areas, listed below.
+	We still don't yet guarantee a fully stable API, though.
+	With new parameters' API we broke the compatibility, as we no longer
+	support direct access to UMF params via (now internal) structures.
+
+	Significant updates:
+	- updated Level Zero Provider
+	- new API to handle UMF parameters (replacing previous struct's)
+	- extended IPC API testing
+	- new Memtarget and Memspace API
+
+	Minor updates:
+	- multiple fixes in the source code
+	- extended code coverage reporting
+	- improved CI and testing
+	- new examples
+	- extended logging
+	- yet more fixes in the building system
+
 Tue Nov 12 2024 Łukasz Stolarczuk <lukasz.stolarczuk@intel.com>
 
 	* Version 0.9.1
diff --git a/examples/ipc_ipcapi/ipc_ipcapi_consumer.c b/examples/ipc_ipcapi/ipc_ipcapi_consumer.c
index 1739e005a..2f55c473f 100644
--- a/examples/ipc_ipcapi/ipc_ipcapi_consumer.c
+++ b/examples/ipc_ipcapi/ipc_ipcapi_consumer.c
@@ -142,6 +142,13 @@ int main(int argc, char *argv[]) {
         goto err_destroy_OS_memory_provider;
     }
 
+    umf_ipc_handler_handle_t ipc_handler;
+    umf_result = umfPoolGetIPCHandler(scalable_pool, &ipc_handler);
+    if (umf_result != UMF_RESULT_SUCCESS) {
+        fprintf(stderr, "[producer] ERROR: get IPC handler failed\n");
+        goto err_destroy_scalable_pool;
+    }
+
     // connect to the producer
     producer_socket = consumer_connect_to_producer(port);
     if (producer_socket < 0) {
@@ -209,7 +216,7 @@ int main(int argc, char *argv[]) {
         len);
 
     void *SHM_ptr;
-    umf_result = umfOpenIPCHandle(scalable_pool, IPC_handle, &SHM_ptr);
+    umf_result = umfOpenIPCHandle(ipc_handler, IPC_handle, &SHM_ptr);
     if (umf_result == UMF_RESULT_ERROR_NOT_SUPPORTED) {
         fprintf(stderr,
                 "[consumer] SKIP: opening the IPC handle is not supported\n");
diff --git a/examples/ipc_level_zero/ipc_level_zero.c b/examples/ipc_level_zero/ipc_level_zero.c
index e81940717..9579244ab 100644
--- a/examples/ipc_level_zero/ipc_level_zero.c
+++ b/examples/ipc_level_zero/ipc_level_zero.c
@@ -180,14 +180,21 @@ int main(void) {
 
     fprintf(stdout, "Consumer pool created.\n");
 
+    umf_ipc_handler_handle_t ipc_handler = 0;
+    umf_result = umfPoolGetIPCHandler(consumer_pool, &ipc_handler);
+    if (umf_result != UMF_RESULT_SUCCESS) {
+        fprintf(stderr, "ERROR: Failed to get IPC handler!\n");
+        return -1;
+    }
+
     void *mapped_buf = NULL;
-    umf_result = umfOpenIPCHandle(consumer_pool, ipc_handle, &mapped_buf);
+    umf_result = umfOpenIPCHandle(ipc_handler, ipc_handle, &mapped_buf);
     if (umf_result != UMF_RESULT_SUCCESS) {
         fprintf(stderr, "ERROR: Failed to open IPC handle!\n");
         return -1;
     }
 
-    fprintf(stdout, "IPC handle opened in the consumer pool.\n");
+    fprintf(stdout, "IPC handle opened.\n");
 
     size_t *tmp_buf = malloc(BUFFER_SIZE);
     ret = level_zero_copy(consumer_context, device, tmp_buf, mapped_buf,
diff --git a/include/umf/ipc.h b/include/umf/ipc.h
index ffe38bfc8..ab47b0971 100644
--- a/include/umf/ipc.h
+++ b/include/umf/ipc.h
@@ -19,6 +19,8 @@ extern "C" {
 
 typedef struct umf_ipc_data_t *umf_ipc_handle_t;
 
+typedef void *umf_ipc_handler_handle_t;
+
 ///
 /// @brief Returns the size of IPC handles for the specified pool.
 /// @param hPool [in] Pool handle
@@ -44,11 +46,11 @@ umf_result_t umfPutIPCHandle(umf_ipc_handle_t ipcHandle);
 
 ///
 /// @brief Open IPC handle retrieved by umfGetIPCHandle.
-/// @param hPool [in] Pool handle where to open the the IPC handle.
+/// @param hIPCHandler [in] IPC Handler handle used to open the IPC handle.
 /// @param ipcHandle [in] IPC handle.
 /// @param ptr [out] pointer to the memory in the current process.
 /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
-umf_result_t umfOpenIPCHandle(umf_memory_pool_handle_t hPool,
+umf_result_t umfOpenIPCHandle(umf_ipc_handler_handle_t hIPCHandler,
                               umf_ipc_handle_t ipcHandle, void **ptr);
 
 ///
@@ -57,6 +59,13 @@ umf_result_t umfOpenIPCHandle(umf_memory_pool_handle_t hPool,
 /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
 umf_result_t umfCloseIPCHandle(void *ptr);
 
+/// @brief Get handle to the IPC handler from existing pool.
+/// @param hPool [in] Pool handle
+/// @param hIPCHandler [out] handle to the IPC handler
+/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
+umf_result_t umfPoolGetIPCHandler(umf_memory_pool_handle_t hPool,
+                                  umf_ipc_handler_handle_t *hIPCHandler);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/licensing/third-party-programs.txt b/licensing/third-party-programs.txt
index 54520c141..8ee09e2e9 100644
--- a/licensing/third-party-programs.txt
+++ b/licensing/third-party-programs.txt
@@ -422,4 +422,544 @@ _______________________________________________________________________________
 
 _______________________________________________________________________________
 
+8. uthash:
+
+  Copyright (c) 2005-2018, Troy D. Hanson  http://troydhanson.github.com/uthash/
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+      * Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+_______________________________________________________________________________
+
+9. google benchmark
+
+   Copyright 2015 Google Inc. All rights reserved.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+   
+_______________________________________________________________________________
+
+9. NVIDIA runtime headers
+
+  Preface
+  -------
+
+  The Software License Agreement in Chapter 1 and the Supplement
+  in Chapter 2 contain license terms and conditions that govern
+  the use of NVIDIA software. By accepting this agreement, you
+  agree to comply with all the terms and conditions applicable
+  to the product(s) included herein.
+
+  1. License Agreement for NVIDIA Software Development Kits
+  ---------------------------------------------------------
+
+
+  Release Date: July 26, 2018
+  ---------------------------
+
+
+  Important NoticeRead before downloading, installing,
+  copying or using the licensed software:
+  -------------------------------------------------------
+
+  This license agreement, including exhibits attached
+  ("Agreement”) is a legal agreement between you and NVIDIA
+  Corporation ("NVIDIA") and governs your use of a NVIDIA
+  software development kit (“SDK”).
+
+  Each SDK has its own set of software and materials, but here
+  is a description of the types of items that may be included in
+  a SDK: source code, header files, APIs, data sets and assets
+  (examples include images, textures, models, scenes, videos,
+  native API input/output files), binary software, sample code,
+  libraries, utility programs, programming code and
+  documentation.
+
+  This Agreement can be accepted only by an adult of legal age
+  of majority in the country in which the SDK is used.
+
+  If you are entering into this Agreement on behalf of a company
+  or other legal entity, you represent that you have the legal
+  authority to bind the entity to this Agreement, in which case
+  “you” will mean the entity you represent.
+
+  If you don’t have the required age or authority to accept
+  this Agreement, or if you don’t accept all the terms and
+  conditions of this Agreement, do not download, install or use
+  the SDK.
+
+  You agree to use the SDK only for purposes that are permitted
+  by (a) this Agreement, and (b) any applicable law, regulation
+  or generally accepted practices or guidelines in the relevant
+  jurisdictions.
+
+
+  1.1. License
+
+
+  1.1.1. License Grant
+
+  Subject to the terms of this Agreement, NVIDIA hereby grants
+  you a non-exclusive, non-transferable license, without the
+  right to sublicense (except as expressly provided in this
+  Agreement) to:
+
+    1. Install and use the SDK,
+
+    2. Modify and create derivative works of sample source code
+      delivered in the SDK, and
+
+    3. Distribute those portions of the SDK that are identified
+      in this Agreement as distributable, as incorporated in
+      object code format into a software application that meets
+      the distribution requirements indicated in this Agreement.
+
+
+  1.1.2. Distribution Requirements
+
+  These are the distribution requirements for you to exercise
+  the distribution grant:
+
+    1. Your application must have material additional
+      functionality, beyond the included portions of the SDK.
+
+    2. The distributable portions of the SDK shall only be
+      accessed by your application.
+
+    3. The following notice shall be included in modifications
+      and derivative works of sample source code distributed:
+      “This software contains source code provided by NVIDIA
+      Corporation.”
+
+    4. Unless a developer tool is identified in this Agreement
+      as distributable, it is delivered for your internal use
+      only.
+
+    5. The terms under which you distribute your application
+      must be consistent with the terms of this Agreement,
+      including (without limitation) terms relating to the
+      license grant and license restrictions and protection of
+      NVIDIA’s intellectual property rights. Additionally, you
+      agree that you will protect the privacy, security and
+      legal rights of your application users.
+
+    6. You agree to notify NVIDIA in writing of any known or
+      suspected distribution or use of the SDK not in compliance
+      with the requirements of this Agreement, and to enforce
+      the terms of your agreements with respect to distributed
+      SDK.
+
+
+  1.1.3. Authorized Users
+
+  You may allow employees and contractors of your entity or of
+  your subsidiary(ies) to access and use the SDK from your
+  secure network to perform work on your behalf.
+
+  If you are an academic institution you may allow users
+  enrolled or employed by the academic institution to access and
+  use the SDK from your secure network.
+
+  You are responsible for the compliance with the terms of this
+  Agreement by your authorized users. If you become aware that
+  your authorized users didn’t follow the terms of this
+  Agreement, you agree to take reasonable steps to resolve the
+  non-compliance and prevent new occurrences.
+
+
+  1.1.4. Pre-Release SDK
+
+  The SDK versions identified as alpha, beta, preview or
+  otherwise as pre-release, may not be fully functional, may
+  contain errors or design flaws, and may have reduced or
+  different security, privacy, accessibility, availability, and
+  reliability standards relative to commercial versions of
+  NVIDIA software and materials. Use of a pre-release SDK may
+  result in unexpected results, loss of data, project delays or
+  other unpredictable damage or loss.
+
+  You may use a pre-release SDK at your own risk, understanding
+  that pre-release SDKs are not intended for use in production
+  or business-critical systems.
+
+  NVIDIA may choose not to make available a commercial version
+  of any pre-release SDK. NVIDIA may also choose to abandon
+  development and terminate the availability of a pre-release
+  SDK at any time without liability.
+
+
+  1.1.5. Updates
+
+  NVIDIA may, at its option, make available patches, workarounds
+  or other updates to this SDK. Unless the updates are provided
+  with their separate governing terms, they are deemed part of
+  the SDK licensed to you as provided in this Agreement. You
+  agree that the form and content of the SDK that NVIDIA
+  provides may change without prior notice to you. While NVIDIA
+  generally maintains compatibility between versions, NVIDIA may
+  in some cases make changes that introduce incompatibilities in
+  future versions of the SDK.
+
+
+  1.1.6. Third Party Licenses
+
+  The SDK may come bundled with, or otherwise include or be
+  distributed with, third party software licensed by a NVIDIA
+  supplier and/or open source software provided under an open
+  source license. Use of third party software is subject to the
+  third-party license terms, or in the absence of third party
+  terms, the terms of this Agreement. Copyright to third party
+  software is held by the copyright holders indicated in the
+  third-party software or license.
+
+
+  1.1.7. Reservation of Rights
+
+  NVIDIA reserves all rights, title, and interest in and to the
+  SDK, not expressly granted to you under this Agreement.
+
+
+  1.2. Limitations
+
+  The following license limitations apply to your use of the
+  SDK:
+
+    1. You may not reverse engineer, decompile or disassemble,
+      or remove copyright or other proprietary notices from any
+      portion of the SDK or copies of the SDK.
+
+    2. Except as expressly provided in this Agreement, you may
+      not copy, sell, rent, sublicense, transfer, distribute,
+      modify, or create derivative works of any portion of the
+      SDK. For clarity, you may not distribute or sublicense the
+      SDK as a stand-alone product.
+
+    3. Unless you have an agreement with NVIDIA for this
+      purpose, you may not indicate that an application created
+      with the SDK is sponsored or endorsed by NVIDIA.
+
+    4. You may not bypass, disable, or circumvent any
+      encryption, security, digital rights management or
+      authentication mechanism in the SDK.
+
+    5. You may not use the SDK in any manner that would cause it
+      to become subject to an open source software license. As
+      examples, licenses that require as a condition of use,
+      modification, and/or distribution that the SDK be:
+
+        a. Disclosed or distributed in source code form;
+
+        b. Licensed for the purpose of making derivative works;
+          or
+
+        c. Redistributable at no charge.
+
+    6. Unless you have an agreement with NVIDIA for this
+      purpose, you may not use the SDK with any system or
+      application where the use or failure of the system or
+      application can reasonably be expected to threaten or
+      result in personal injury, death, or catastrophic loss.
+      Examples include use in avionics, navigation, military,
+      medical, life support or other life critical applications.
+      NVIDIA does not design, test or manufacture the SDK for
+      these critical uses and NVIDIA shall not be liable to you
+      or any third party, in whole or in part, for any claims or
+      damages arising from such uses.
+
+    7. You agree to defend, indemnify and hold harmless NVIDIA
+      and its affiliates, and their respective employees,
+      contractors, agents, officers and directors, from and
+      against any and all claims, damages, obligations, losses,
+      liabilities, costs or debt, fines, restitutions and
+      expenses (including but not limited to attorney’s fees
+      and costs incident to establishing the right of
+      indemnification) arising out of or related to your use of
+      the SDK outside of the scope of this Agreement, or not in
+      compliance with its terms.
+
+
+  1.3. Ownership
+
+    1.  NVIDIA or its licensors hold all rights, title and
+      interest in and to the SDK and its modifications and
+      derivative works, including their respective intellectual
+      property rights, subject to your rights described in this
+      section. This SDK may include software and materials from
+      NVIDIA’s licensors, and these licensors are intended
+      third party beneficiaries that may enforce this Agreement
+      with respect to their intellectual property rights.
+
+    2.  You hold all rights, title and interest in and to your
+      applications and your derivative works of the sample
+      source code delivered in the SDK, including their
+      respective intellectual property rights, subject to
+      NVIDIA’s rights described in this section.
+
+    3. You may, but don’t have to, provide to NVIDIA
+      suggestions, feature requests or other feedback regarding
+      the SDK, including possible enhancements or modifications
+      to the SDK. For any feedback that you voluntarily provide,
+      you hereby grant NVIDIA and its affiliates a perpetual,
+      non-exclusive, worldwide, irrevocable license to use,
+      reproduce, modify, license, sublicense (through multiple
+      tiers of sublicensees), and distribute (through multiple
+      tiers of distributors) it without the payment of any
+      royalties or fees to you. NVIDIA will use feedback at its
+      choice. NVIDIA is constantly looking for ways to improve
+      its products, so you may send feedback to NVIDIA through
+      the developer portal at https://developer.nvidia.com.
+
+
+  1.4. No Warranties
+
+  THE SDK IS PROVIDED BY NVIDIA “AS IS” AND “WITH ALL
+  FAULTS.” TO THE MAXIMUM EXTENT PERMITTED BY LAW, NVIDIA AND
+  ITS AFFILIATES EXPRESSLY DISCLAIM ALL WARRANTIES OF ANY KIND
+  OR NATURE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING,
+  BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+  FOR A PARTICULAR PURPOSE, TITLE, NON-INFRINGEMENT, OR THE
+  ABSENCE OF ANY DEFECTS THEREIN, WHETHER LATENT OR PATENT. NO
+  WARRANTY IS MADE ON THE BASIS OF TRADE USAGE, COURSE OF
+  DEALING OR COURSE OF TRADE.
+
+
+  1.5. Limitation of Liability
+
+  TO THE MAXIMUM EXTENT PERMITTED BY LAW, NVIDIA AND ITS
+  AFFILIATES SHALL NOT BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+  PUNITIVE OR CONSEQUENTIAL DAMAGES, OR ANY LOST PROFITS, LOSS
+  OF USE, LOSS OF DATA OR LOSS OF GOODWILL, OR THE COSTS OF
+  PROCURING SUBSTITUTE PRODUCTS, ARISING OUT OF OR IN CONNECTION
+  WITH THIS AGREEMENT OR THE USE OR PERFORMANCE OF THE SDK,
+  WHETHER SUCH LIABILITY ARISES FROM ANY CLAIM BASED UPON BREACH
+  OF CONTRACT, BREACH OF WARRANTY, TORT (INCLUDING NEGLIGENCE),
+  PRODUCT LIABILITY OR ANY OTHER CAUSE OF ACTION OR THEORY OF
+  LIABILITY. IN NO EVENT WILL NVIDIA’S AND ITS AFFILIATES
+  TOTAL CUMULATIVE LIABILITY UNDER OR ARISING OUT OF THIS
+  AGREEMENT EXCEED US$10.00. THE NATURE OF THE LIABILITY OR THE
+  NUMBER OF CLAIMS OR SUITS SHALL NOT ENLARGE OR EXTEND THIS
+  LIMIT.
+
+  These exclusions and limitations of liability shall apply
+  regardless if NVIDIA or its affiliates have been advised of
+  the possibility of such damages, and regardless of whether a
+  remedy fails its essential purpose. These exclusions and
+  limitations of liability form an essential basis of the
+  bargain between the parties, and, absent any of these
+  exclusions or limitations of liability, the provisions of this
+  Agreement, including, without limitation, the economic terms,
+  would be substantially different.
+
+
+  1.6. Termination
+
+    1. This Agreement will continue to apply until terminated by
+      either you or NVIDIA as described below.
+
+    2. If you want to terminate this Agreement, you may do so by
+      stopping to use the SDK.
+
+    3. NVIDIA may, at any time, terminate this Agreement if:
+
+        a. (i) you fail to comply with any term of this
+          Agreement and the non-compliance is not fixed within
+          thirty (30) days following notice from NVIDIA (or
+          immediately if you violate NVIDIA’s intellectual
+          property rights);
+
+        b. (ii) you commence or participate in any legal
+          proceeding against NVIDIA with respect to the SDK; or
+
+        c. (iii) NVIDIA decides to no longer provide the SDK in
+          a country or, in NVIDIA’s sole discretion, the
+          continued use of it is no longer commercially viable.
+
+    4. Upon any termination of this Agreement, you agree to
+      promptly discontinue use of the SDK and destroy all copies
+      in your possession or control. Your prior distributions in
+      accordance with this Agreement are not affected by the
+      termination of this Agreement. Upon written request, you
+      will certify in writing that you have complied with your
+      commitments under this section. Upon any termination of
+      this Agreement all provisions survive except for the
+      license grant provisions.
+
+
+  1.7. General
+
+  If you wish to assign this Agreement or your rights and
+  obligations, including by merger, consolidation, dissolution
+  or operation of law, contact NVIDIA to ask for permission. Any
+  attempted assignment not approved by NVIDIA in writing shall
+  be void and of no effect. NVIDIA may assign, delegate or
+  transfer this Agreement and its rights and obligations, and if
+  to a non-affiliate you will be notified.
+
+  You agree to cooperate with NVIDIA and provide reasonably
+  requested information to verify your compliance with this
+  Agreement.
+
+  This Agreement will be governed in all respects by the laws of
+  the United States and of the State of Delaware as those laws
+  are applied to contracts entered into and performed entirely
+  within Delaware by Delaware residents, without regard to the
+  conflicts of laws principles. The United Nations Convention on
+  Contracts for the International Sale of Goods is specifically
+  disclaimed. You agree to all terms of this Agreement in the
+  English language.
+
+  The state or federal courts residing in Santa Clara County,
+  California shall have exclusive jurisdiction over any dispute
+  or claim arising out of this Agreement. Notwithstanding this,
+  you agree that NVIDIA shall still be allowed to apply for
+  injunctive remedies or an equivalent type of urgent legal
+  relief in any jurisdiction.
+
+  If any court of competent jurisdiction determines that any
+  provision of this Agreement is illegal, invalid or
+  unenforceable, such provision will be construed as limited to
+  the extent necessary to be consistent with and fully
+  enforceable under the law and the remaining provisions will
+  remain in full force and effect. Unless otherwise specified,
+  remedies are cumulative.
+
+  Each party acknowledges and agrees that the other is an
+  independent contractor in the performance of this Agreement.
+
+  The SDK has been developed entirely at private expense and is
+  “commercial items” consisting of “commercial computer
+  software” and “commercial computer software
+  documentation” provided with RESTRICTED RIGHTS. Use,
+  duplication or disclosure by the U.S. Government or a U.S.
+  Government subcontractor is subject to the restrictions in
+  this Agreement pursuant to DFARS 227.7202-3(a) or as set forth
+  in subparagraphs (c)(1) and (2) of the Commercial Computer
+  Software - Restricted Rights clause at FAR 52.227-19, as
+  applicable. Contractor/manufacturer is NVIDIA, 2788 San Tomas
+  Expressway, Santa Clara, CA 95051.
+
+  The SDK is subject to United States export laws and
+  regulations. You agree that you will not ship, transfer or
+  export the SDK into any country, or use the SDK in any manner,
+  prohibited by the United States Bureau of Industry and
+  Security or economic sanctions regulations administered by the
+  U.S. Department of Treasury’s Office of Foreign Assets
+  Control (OFAC), or any applicable export laws, restrictions or
+  regulations. These laws include restrictions on destinations,
+  end users and end use. By accepting this Agreement, you
+  confirm that you are not a resident or citizen of any country
+  currently embargoed by the U.S. and that you are not otherwise
+  prohibited from receiving the SDK.
+
+  Any notice delivered by NVIDIA to you under this Agreement
+  will be delivered via mail, email or fax. You agree that any
+  notices that NVIDIA sends you electronically will satisfy any
+  legal communication requirements. Please direct your legal
+  notices or other correspondence to NVIDIA Corporation, 2788
+  San Tomas Expressway, Santa Clara, California 95051, United
+  States of America, Attention: Legal Department.
+
+  This Agreement and any exhibits incorporated into this
+  Agreement constitute the entire agreement of the parties with
+  respect to the subject matter of this Agreement and supersede
+  all prior negotiations or documentation exchanged between the
+  parties relating to this SDK license. Any additional and/or
+  conflicting terms on documents issued by you are null, void,
+  and invalid. Any amendment or waiver under this Agreement
+  shall be in writing and signed by representatives of both
+  parties.
+
+
+  2. CUDA Toolkit Supplement to Software License Agreement for
+  NVIDIA Software Development Kits
+  ------------------------------------------------------------
+
+
+  Release date: August 16, 2018
+  -----------------------------
+
+  The terms in this supplement govern your use of the NVIDIA
+  CUDA Toolkit SDK under the terms of your license agreement
+  (“Agreement”) as modified by this supplement. Capitalized
+  terms used but not defined below have the meaning assigned to
+  them in the Agreement.
+
+  This supplement is an exhibit to the Agreement and is
+  incorporated as an integral part of the Agreement. In the
+  event of conflict between the terms in this supplement and the
+  terms in the Agreement, the terms in this supplement govern.
+
+
+  2.1. License Scope
+
+  The SDK is licensed for you to develop applications only for
+  use in systems with NVIDIA GPUs.
+
+
+  2.2. Distribution
+
+  The portions of the SDK that are distributable under the
+  Agreement are listed in Attachment A.
+
+
+  2.3. Operating Systems
+
+  Those portions of the SDK designed exclusively for use on the
+  Linux or FreeBSD operating systems, or other operating systems
+  derived from the source code to these operating systems, may
+  be copied and redistributed for use in accordance with this
+  Agreement, provided that the object code files are not
+  modified in any way (except for unzipping of compressed
+  files).
+
+
+  2.4. Audio and Video Encoders and Decoders
+
+  You acknowledge and agree that it is your sole responsibility
+  to obtain any additional third-party licenses required to
+  make, have made, use, have used, sell, import, and offer for
+  sale your products or services that include or incorporate any
+  third-party software and content relating to audio and/or
+  video encoders and decoders from, including but not limited
+  to, Microsoft, Thomson, Fraunhofer IIS, Sisvel S.p.A.,
+  MPEG-LA, and Coding Technologies. NVIDIA does not grant to you
+  under this Agreement any necessary patent or other rights with
+  respect to any audio and/or video encoders and decoders.
+
+
+  2.5. Licensing
+
+  If the distribution terms in this Agreement are not suitable
+  for your organization, or for any questions regarding this
+  Agreement, please contact NVIDIA at
+  nvidia-compute-license-questions@nvidia.com.
+
+_______________________________________________________________________________
+
 *Other names and brands may be claimed as the property of others.
diff --git a/scripts/docs_config/examples.rst b/scripts/docs_config/examples.rst
index a84dd3aa2..c58e7fc22 100644
--- a/scripts/docs_config/examples.rst
+++ b/scripts/docs_config/examples.rst
@@ -194,12 +194,15 @@ to another process it can be opened by the :any:`umfOpenIPCHandle` function.
 
 .. code-block:: c
 
+    umf_ipc_handler_handle_t ipc_handler = 0;
+    umf_result = umfPoolGetIPCHandler(consumer_pool, &ipc_handler);
+
     void *mapped_buf = NULL;
-    umf_result = umfOpenIPCHandle(consumer_pool, ipc_handle, &mapped_buf);
+    umf_result = umfOpenIPCHandle(ipc_handler, ipc_handle, &mapped_buf);
 
-The :any:`umfOpenIPCHandle` function requires the memory pool handle and the IPC handle as input parameters. It maps
+The :any:`umfOpenIPCHandle` function requires the IPC handler and the IPC handle as input parameters. The IPC handler maps
 the handle to the current process address space and returns the pointer to the same memory region that was allocated
-in the producer process.
+in the producer process. To retrieve the IPC handler, the :any:`umfPoolGetIPCHandler` function is used.
 
 .. note::
     The virtual addresses of the memory region referred to by the IPC handle may not be the same in the producer and consumer processes.
diff --git a/src/ipc.c b/src/ipc.c
index 5df755876..1b479fd7c 100644
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -119,12 +119,18 @@ umf_result_t umfPutIPCHandle(umf_ipc_handle_t umfIPCHandle) {
     return ret;
 }
 
-umf_result_t umfOpenIPCHandle(umf_memory_pool_handle_t hPool,
+umf_result_t umfOpenIPCHandle(umf_ipc_handler_handle_t hIPCHandler,
                               umf_ipc_handle_t umfIPCHandle, void **ptr) {
 
-    // We cannot use umfPoolGetMemoryProvider function because it returns
-    // upstream provider but we need tracking one
-    umf_memory_provider_handle_t hProvider = hPool->provider;
+    // IPC handler is an instance of tracking memory provider
+    if (*(uint32_t *)hIPCHandler != UMF_VERSION_CURRENT) {
+        // It is a temporary hack to verify that user passes correct IPC handler,
+        // not a pool handle, as it was required in previous version.
+        LOG_ERR("Invalid IPC handler.");
+        return UMF_RESULT_ERROR_INVALID_ARGUMENT;
+    }
+
+    umf_memory_provider_handle_t hProvider = hIPCHandler;
     void *base = NULL;
 
     umf_result_t ret = umfMemoryProviderOpenIPCHandle(
@@ -153,3 +159,26 @@ umf_result_t umfCloseIPCHandle(void *ptr) {
     return umfMemoryProviderCloseIPCHandle(hProvider, allocInfo.base,
                                            allocInfo.baseSize);
 }
+
+umf_result_t umfPoolGetIPCHandler(umf_memory_pool_handle_t hPool,
+                                  umf_ipc_handler_handle_t *hIPCHandler) {
+    if (hPool == NULL) {
+        LOG_ERR("Pool handle is NULL.");
+        return UMF_RESULT_ERROR_INVALID_ARGUMENT;
+    }
+
+    if (hIPCHandler == NULL) {
+        LOG_ERR("hIPCHandler is NULL.");
+        return UMF_RESULT_ERROR_INVALID_ARGUMENT;
+    }
+
+    // We cannot use umfPoolGetMemoryProvider function because it returns
+    // upstream provider but we need tracking one
+    umf_memory_provider_handle_t hProvider = hPool->provider;
+
+    // We are using tracking provider as an IPC handler because
+    // it is doing IPC caching.
+    *hIPCHandler = (umf_ipc_handler_handle_t)hProvider;
+
+    return UMF_RESULT_SUCCESS;
+}
diff --git a/src/libumf.def b/src/libumf.def
index a81492af3..7666c146b 100644
--- a/src/libumf.def
+++ b/src/libumf.def
@@ -101,6 +101,7 @@ EXPORTS
     umfPoolCreateFromMemspace
     umfPoolDestroy
     umfPoolFree
+    umfPoolGetIPCHandler
     umfPoolGetIPCHandleSize
     umfPoolGetLastAllocationError
     umfPoolGetTag
diff --git a/src/libumf.map b/src/libumf.map
index 4c60b87c3..5d1ca3b77 100644
--- a/src/libumf.map
+++ b/src/libumf.map
@@ -95,6 +95,7 @@ UMF_1.0 {
         umfPoolCreateFromMemspace;
         umfPoolDestroy;
         umfPoolFree;
+        umfPoolGetIPCHandler;
         umfPoolGetIPCHandleSize;
         umfPoolGetLastAllocationError;
         umfPoolGetMemoryProvider;


Test patch:
diff --git a/test/common/ipc_common.c b/test/common/ipc_common.c
index 9d78afc9c..140927079 100644
--- a/test/common/ipc_common.c
+++ b/test/common/ipc_common.c
@@ -138,6 +138,13 @@ int run_consumer(int port, umf_memory_pool_ops_t *pool_ops, void *pool_params,
         goto err_umfMemoryProviderDestroy;
     }
 
+    umf_ipc_handler_handle_t ipc_handler;
+    umf_result = umfPoolGetIPCHandler(pool, &ipc_handler);
+    if (umf_result != UMF_RESULT_SUCCESS) {
+        fprintf(stderr, "[consumer] ERROR: get IPC handler failed\n");
+        goto err_umfMemoryPoolDestroy;
+    }
+
     producer_socket = consumer_connect(port);
     if (producer_socket < 0) {
         goto err_umfMemoryPoolDestroy;
@@ -195,7 +202,7 @@ int run_consumer(int port, umf_memory_pool_ops_t *pool_ops, void *pool_params,
         len);
 
     void *SHM_ptr;
-    umf_result = umfOpenIPCHandle(pool, IPC_handle, &SHM_ptr);
+    umf_result = umfOpenIPCHandle(ipc_handler, IPC_handle, &SHM_ptr);
     if (umf_result == UMF_RESULT_ERROR_NOT_SUPPORTED) {
         fprintf(stderr,
                 "[consumer] SKIP: opening the IPC handle is not supported\n");
diff --git a/test/ipcFixtures.hpp b/test/ipcFixtures.hpp
index 6fbacfa22..fd5260d1b 100644
--- a/test/ipcFixtures.hpp
+++ b/test/ipcFixtures.hpp
@@ -194,12 +194,17 @@ TEST_P(umfIpcTest, BasicFlow) {
     ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
     ASSERT_EQ(handleFullSize, handleHalfSize);
 
+    umf_ipc_handler_handle_t ipcHandler = nullptr;
+    ret = umfPoolGetIPCHandler(pool.get(), &ipcHandler);
+    ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
+    ASSERT_NE(ipcHandler, nullptr);
+
     void *fullArray = nullptr;
-    ret = umfOpenIPCHandle(pool.get(), ipcHandleFull, &fullArray);
+    ret = umfOpenIPCHandle(ipcHandler, ipcHandleFull, &fullArray);
     ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
 
     void *halfArray = nullptr;
-    ret = umfOpenIPCHandle(pool.get(), ipcHandleHalf, &halfArray);
+    ret = umfOpenIPCHandle(ipcHandler, ipcHandleHalf, &halfArray);
     ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
 
     std::vector<int> actual_data(SIZE);
@@ -262,8 +267,13 @@ TEST_P(umfIpcTest, GetPoolByOpenedHandle) {
 
         for (size_t pool_id = 0; pool_id < NUM_POOLS; pool_id++) {
             void *ptr = nullptr;
+            umf_ipc_handler_handle_t ipcHandler = nullptr;
             ret =
-                umfOpenIPCHandle(pools_to_open[pool_id].get(), ipcHandle, &ptr);
+                umfPoolGetIPCHandler(pools_to_open[pool_id].get(), &ipcHandler);
+            ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
+            ASSERT_NE(ipcHandler, nullptr);
+
+            ret = umfOpenIPCHandle(ipcHandler, ipcHandle, &ptr);
             ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
             openedPtrs[pool_id][i] = ptr;
         }
@@ -296,16 +306,22 @@ TEST_P(umfIpcTest, GetPoolByOpenedHandle) {
 TEST_P(umfIpcTest, AllocFreeAllocTest) {
     constexpr size_t SIZE = 64 * 1024;
     umf::pool_unique_handle_t pool = makePool();
+    umf_ipc_handler_handle_t ipcHandler = nullptr;
+
+    umf_result_t ret = umfPoolGetIPCHandler(pool.get(), &ipcHandler);
+    ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
+    ASSERT_NE(ipcHandler, nullptr);
+
     void *ptr = umfPoolMalloc(pool.get(), SIZE);
     EXPECT_NE(ptr, nullptr);
 
     umf_ipc_handle_t ipcHandle = nullptr;
     size_t handleSize = 0;
-    umf_result_t ret = umfGetIPCHandle(ptr, &ipcHandle, &handleSize);
+    ret = umfGetIPCHandle(ptr, &ipcHandle, &handleSize);
     ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
 
     void *opened_ptr = nullptr;
-    ret = umfOpenIPCHandle(pool.get(), ipcHandle, &opened_ptr);
+    ret = umfOpenIPCHandle(ipcHandler, ipcHandle, &opened_ptr);
     ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
 
     ret = umfCloseIPCHandle(opened_ptr);
@@ -327,7 +343,7 @@ TEST_P(umfIpcTest, AllocFreeAllocTest) {
     ret = umfGetIPCHandle(ptr, &ipcHandle, &handleSize);
     ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
 
-    ret = umfOpenIPCHandle(pool.get(), ipcHandle, &opened_ptr);
+    ret = umfOpenIPCHandle(ipcHandler, ipcHandle, &opened_ptr);
     ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
 
     ret = umfCloseIPCHandle(opened_ptr);
@@ -345,11 +361,22 @@ TEST_P(umfIpcTest, AllocFreeAllocTest) {
     EXPECT_EQ(stat.openCount, stat.closeCount);
 }
 
-TEST_P(umfIpcTest, openInTwoPools) {
+TEST_P(umfIpcTest, openInTwoIpcHandlers) {
     constexpr size_t SIZE = 100;
     std::vector<int> expected_data(SIZE);
     umf::pool_unique_handle_t pool1 = makePool();
     umf::pool_unique_handle_t pool2 = makePool();
+    umf_ipc_handler_handle_t ipcHandler1 = nullptr;
+    umf_ipc_handler_handle_t ipcHandler2 = nullptr;
+
+    umf_result_t ret = umfPoolGetIPCHandler(pool1.get(), &ipcHandler1);
+    ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
+    ASSERT_NE(ipcHandler1, nullptr);
+
+    ret = umfPoolGetIPCHandler(pool2.get(), &ipcHandler2);
+    ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
+    ASSERT_NE(ipcHandler2, nullptr);
+
     void *ptr = umfPoolMalloc(pool1.get(), sizeof(expected_data[0]) * SIZE);
     EXPECT_NE(ptr, nullptr);
 
@@ -358,15 +385,15 @@ TEST_P(umfIpcTest, openInTwoPools) {
 
     umf_ipc_handle_t ipcHandle = nullptr;
     size_t handleSize = 0;
-    umf_result_t ret = umfGetIPCHandle(ptr, &ipcHandle, &handleSize);
+    ret = umfGetIPCHandle(ptr, &ipcHandle, &handleSize);
     ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
 
     void *openedPtr1 = nullptr;
-    ret = umfOpenIPCHandle(pool1.get(), ipcHandle, &openedPtr1);
+    ret = umfOpenIPCHandle(ipcHandler1, ipcHandle, &openedPtr1);
     ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
 
     void *openedPtr2 = nullptr;
-    ret = umfOpenIPCHandle(pool2.get(), ipcHandle, &openedPtr2);
+    ret = umfOpenIPCHandle(ipcHandler2, ipcHandle, &openedPtr2);
     ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
 
     ret = umfPutIPCHandle(ipcHandle);
@@ -447,6 +474,7 @@ TEST_P(umfIpcTest, ConcurrentGetPutHandles) {
 }
 
 TEST_P(umfIpcTest, ConcurrentOpenCloseHandles) {
+    umf_result_t ret;
     std::vector<void *> ptrs;
     constexpr size_t ALLOC_SIZE = 100;
     constexpr size_t NUM_POINTERS = 100;
@@ -462,21 +490,25 @@ TEST_P(umfIpcTest, ConcurrentOpenCloseHandles) {
     for (size_t i = 0; i < NUM_POINTERS; ++i) {
         umf_ipc_handle_t ipcHandle;
         size_t handleSize;
-        umf_result_t ret = umfGetIPCHandle(ptrs[i], &ipcHandle, &handleSize);
+        ret = umfGetIPCHandle(ptrs[i], &ipcHandle, &handleSize);
         ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
         ipcHandles[i] = ipcHandle;
     }
 
     std::array<std::vector<void *>, NTHREADS> openedIpcHandles;
+    umf_ipc_handler_handle_t ipcHandler = nullptr;
+    ret = umfPoolGetIPCHandler(pool.get(), &ipcHandler);
+    ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
+    ASSERT_NE(ipcHandler, nullptr);
 
     umf_test::syncthreads_barrier syncthreads(NTHREADS);
 
     auto openHandlesFn = [&ipcHandles, &openedIpcHandles, &syncthreads,
-                          &pool](size_t tid) {
+                          ipcHandler](size_t tid) {
         syncthreads();
         for (auto ipcHandle : ipcHandles) {
             void *ptr;
-            umf_result_t ret = umfOpenIPCHandle(pool.get(), ipcHandle, &ptr);
+            umf_result_t ret = umfOpenIPCHandle(ipcHandler, ipcHandle, &ptr);
             ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
             openedIpcHandles[tid].push_back(ptr);
         }
@@ -495,12 +527,12 @@ TEST_P(umfIpcTest, ConcurrentOpenCloseHandles) {
     umf_test::parallel_exec(NTHREADS, closeHandlesFn);
 
     for (auto ipcHandle : ipcHandles) {
-        umf_result_t ret = umfPutIPCHandle(ipcHandle);
+        ret = umfPutIPCHandle(ipcHandle);
         EXPECT_EQ(ret, UMF_RESULT_SUCCESS);
     }
 
     for (void *ptr : ptrs) {
-        umf_result_t ret = umfPoolFree(pool.get(), ptr);
+        ret = umfPoolFree(pool.get(), ptr);
         EXPECT_EQ(ret, UMF_RESULT_SUCCESS);
     }
 
diff --git a/test/ipc_negative.cpp b/test/ipc_negative.cpp
index 5407422ea..5c4cccf22 100644
--- a/test/ipc_negative.cpp
+++ b/test/ipc_negative.cpp
@@ -47,7 +47,11 @@ TEST_F(IpcNotSupported, OpenIPCHandleNotSupported) {
     // This data doesn't matter, as the ipc call is no-op
     std::array<uint8_t, 128> ipc_data = {};
     void *ptr;
-    auto ret = umfOpenIPCHandle(
-        pool, reinterpret_cast<umf_ipc_handle_t>(&ipc_data), &ptr);
+    umf_ipc_handler_handle_t ipc_handler;
+    auto ret = umfPoolGetIPCHandler(pool, &ipc_handler);
+    ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
+
+    ret = umfOpenIPCHandle(ipc_handler,
+                           reinterpret_cast<umf_ipc_handle_t>(&ipc_data), &ptr);
     EXPECT_EQ(ret, UMF_RESULT_ERROR_NOT_SUPPORTED);
 }
diff --git a/test/utils/utils_linux.cpp b/test/utils/utils_linux.cpp
index 7aa0a9d83..1815a1a78 100644
--- a/test/utils/utils_linux.cpp
+++ b/test/utils/utils_linux.cpp
@@ -2,6 +2,7 @@
 // Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
+#include <cstdint>
 #include <sys/mman.h>
 
 #include "base.hpp"
@@ -169,3 +170,19 @@ TEST_F(test, utils_open) {
     EXPECT_EQ(utils_file_open(NULL), -1);
     EXPECT_EQ(utils_file_open_or_create(NULL), -1);
 }
+
+TEST_F(test, utils_align_ptr_up_size_down) {
+    uintptr_t ptr = 0x4000;
+    size_t size = 0x8000;
+    size_t alignment = 0x4000;
+    utils_align_ptr_up_size_down((void **)&ptr, &size, alignment);
+    EXPECT_EQ(ptr, 0x4000);
+    EXPECT_EQ(size, 0x8000);
+
+    ptr = 0x4001;
+    size = 0x8000;
+    alignment = 0x4000;
+    utils_align_ptr_up_size_down((void **)&ptr, &size, alignment);
+    EXPECT_EQ(ptr, 0x8000);
+    EXPECT_EQ(size, 0x4001);
+}