diff --git a/CMakeLists.txt b/CMakeLists.txt
index 89f0cca41..9b09042b2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -653,6 +653,8 @@ if(CUDA_FOUND)
solver_adapter
GpuBuffer
GpuView
+ gpu_ad
+ gpu_linear_two_phase_material
PROPERTIES LABELS ${gpu_label})
endif()
diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake
index fe4e8ec74..4e5cd5e5c 100644
--- a/CMakeLists_files.cmake
+++ b/CMakeLists_files.cmake
@@ -448,6 +448,20 @@ if (HAVE_CUDA)
ADD_CUDA_OR_HIP_FILE(TEST_SOURCE_FILES tests test_cuVector_operations.cpp)
ADD_CUDA_OR_HIP_FILE(TEST_SOURCE_FILES tests test_safe_conversion.cpp)
ADD_CUDA_OR_HIP_FILE(TEST_SOURCE_FILES tests test_solver_adapter.cpp)
+ ADD_CUDA_OR_HIP_FILE(TEST_SOURCE_FILES tests test_gpu_ad.cu)
+ ADD_CUDA_OR_HIP_FILE(TEST_SOURCE_FILES tests test_gpu_linear_two_phase_material.cu)
+
+ # for loop providing the flag --expt-relaxed-constexpr to fix some cuda issues with constexpr
+ if(NOT CONVERT_CUDA_TO_HIP)
+ set(CU_FILES_NEEDING_RELAXED_CONSTEXPR
+ tests/gpuistl/test_gpu_ad.cu
+ tests/gpuistl/gpu_linear_two_phase_material.cu
+ )
+
+ foreach(file ${LIST_OF_FILES})
+ set_source_file_properties(${file} "--expt-relaxed-constexpr")
+ endforeach()
+ endif()
endif()
if(USE_BDA_BRIDGE)
diff --git a/tests/gpuistl/test_gpu_ad.cu b/tests/gpuistl/test_gpu_ad.cu
new file mode 100644
index 000000000..2bb0075b0
--- /dev/null
+++ b/tests/gpuistl/test_gpu_ad.cu
@@ -0,0 +1,52 @@
+/*
+ Copyright 2024 SINTEF AS
+ This file is part of the Open Porous Media project (OPM).
+ OPM is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ OPM is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with OPM. If not, see .
+*/
+#include
+
+#define BOOST_TEST_MODULE TestGpuAD
+
+#include
+#include
+#include
+#include
+
+namespace{
+__global__ void instansiate_ad_object(Opm::DenseAd::Evaluation* adObj, double value){
+ *adObj = Opm::DenseAd::Evaluation(value, 0);
+}
+
+//TODO add more comprenehsive AD tests
+
+} // END EMPTY NAMESPACE
+
+
+BOOST_AUTO_TEST_CASE(TestInstansiateADObject)
+{
+ using Evaluation = Opm::DenseAd::Evaluation;
+ double testValue = 123.456;
+ Evaluation cpuMadeAd = Evaluation(testValue, 0);
+
+ Evaluation gpuMadeAd[1]; // allocate space for one more AD object on the CPU
+ Evaluation *d_ad;
+
+ // allocate space on GPU, run kernel, and move results back to the CPU
+ OPM_GPU_SAFE_CALL(cudaMalloc(&d_ad, sizeof(Evaluation)));
+ instansiate_ad_object<<<1,1>>>(d_ad, testValue);
+ OPM_GPU_SAFE_CALL(cudaDeviceSynchronize());
+ OPM_GPU_SAFE_CALL(cudaMemcpy(&gpuMadeAd, d_ad, sizeof(Evaluation), cudaMemcpyDeviceToHost));
+ OPM_GPU_SAFE_CALL(cudaFree(d_ad));
+
+ // Check that the object made in a GPU kernel is equivalent to that made on the CPU
+ BOOST_CHECK(cpuMadeAd == gpuMadeAd[0]);
+}
diff --git a/tests/gpuistl/test_gpu_linear_two_phase_material.cu b/tests/gpuistl/test_gpu_linear_two_phase_material.cu
new file mode 100644
index 000000000..72c99e65a
--- /dev/null
+++ b/tests/gpuistl/test_gpu_linear_two_phase_material.cu
@@ -0,0 +1,102 @@
+/*
+ Copyright 2024 SINTEF AS
+ This file is part of the Open Porous Media project (OPM).
+ OPM is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ OPM is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with OPM. If not, see .
+*/
+#include
+
+#define BOOST_TEST_MODULE TestGpuLinearTwoPhaseMaterial
+
+#include
+
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+ // these types are taken from Norne
+ using Scalar = float;
+ using ValueVector = std::vector;
+ using GPUBuffer = Opm::gpuistl::GpuBuffer;
+ using GPUView = Opm::gpuistl::GpuView;
+
+ using TraitsT = Opm::TwoPhaseMaterialTraits;
+ using CPUParams = Opm::PiecewiseLinearTwoPhaseMaterialParams;
+ using constGPUBufferParams = Opm::PiecewiseLinearTwoPhaseMaterialParams;
+ using GPUBufferParams = Opm::PiecewiseLinearTwoPhaseMaterialParams;
+ using GPUViewParams = Opm::PiecewiseLinearTwoPhaseMaterialParams;
+
+ using CPUTwoPhaseMaterialLaw = Opm::PiecewiseLinearTwoPhaseMaterial;
+ using GPUTwoPhaseViewMaterialLaw = Opm::PiecewiseLinearTwoPhaseMaterial;
+ using NorneEvaluation = Opm::DenseAd::Evaluation;
+
+__global__ void gpuTwoPhaseSatPcnwWrapper(GPUTwoPhaseViewMaterialLaw::Params params, NorneEvaluation Sw, NorneEvaluation* res){
+ *res = GPUTwoPhaseViewMaterialLaw::twoPhaseSatPcnw(params, Sw);
+}
+
+BOOST_AUTO_TEST_CASE(TestSimpleInterpolation)
+{
+ CPUParams cpuParams;
+ GPUViewParams gpuViewParams;
+
+ ValueVector cx = {0.0, 0.5, 1.0};
+ ValueVector cy = {0.0, 0.9, 1.0};
+ const GPUBuffer gx(cx);
+ const GPUBuffer gy(cy);
+
+ cpuParams.setPcnwSamples(cx, cy);
+ cpuParams.setKrwSamples(cx, cy);
+ cpuParams.setKrnSamples(cx, cy);
+ cpuParams.finalize();
+
+ constGPUBufferParams gpuBufferParams(gx, gy, gx, gy, gx, gy);
+
+ gpuViewParams = Opm::gpuistl::make_view(gpuBufferParams);
+
+ ValueVector testXs = {-1.0, 0, 0.1, 0.3, 0.5, 0.7, 0.9, 0.99, 1.0, 1.1};
+
+ for (Scalar x_i : testXs){
+ auto cpuMadeAd = NorneEvaluation(x_i, 0);
+ NorneEvaluation cpuInterpolatedEval = CPUTwoPhaseMaterialLaw::twoPhaseSatPcnw(cpuParams, cpuMadeAd);
+
+ NorneEvaluation* gpuAdInput;
+ NorneEvaluation* gpuAdResOnGPU;
+ NorneEvaluation gpuAdResOnCPU[1];
+
+ OPM_GPU_SAFE_CALL(cudaMalloc(&gpuAdInput, sizeof(NorneEvaluation)));
+ OPM_GPU_SAFE_CALL(cudaMalloc(&gpuAdResOnGPU, sizeof(NorneEvaluation)));
+
+ OPM_GPU_SAFE_CALL(cudaMemcpy(gpuAdInput, &cpuMadeAd, sizeof(NorneEvaluation), cudaMemcpyHostToDevice));
+ gpuTwoPhaseSatPcnwWrapper<<<1,1>>>(gpuViewParams, *gpuAdInput, gpuAdResOnGPU);
+ OPM_GPU_SAFE_CALL(cudaDeviceSynchronize());
+ OPM_GPU_SAFE_CALL(cudaMemcpy(gpuAdResOnCPU, gpuAdResOnGPU, sizeof(NorneEvaluation), cudaMemcpyDeviceToHost));
+
+ BOOST_CHECK(gpuAdResOnCPU[0] == cpuInterpolatedEval);
+ }
+}