From 9251c86d517788c23048d84c5d6e138ad2175e18 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Sun, 8 Mar 2026 12:37:12 -0400 Subject: [PATCH 01/73] Attempt to create constructor for KokkosBSpline --- BSplineKokkos.cpp | 24 ++++++++++++++++++++++++ BSplineKokkos.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 BSplineKokkos.cpp create mode 100644 BSplineKokkos.h diff --git a/BSplineKokkos.cpp b/BSplineKokkos.cpp new file mode 100644 index 0000000..70ada2b --- /dev/null +++ b/BSplineKokkos.cpp @@ -0,0 +1,24 @@ +#include "BSplineKokkos.h" +#include +#include +#include + +BSplineKokkos::BSplineKokkos(int orderC, std::vector& ctrlPtsC, std::vector& knotsC, std::vector& weightsC) { + order = orderC; + //Allocate appropriate view space based on the number of control points, copy the data over to view + ctrlPts("ctrlPts", ctrlPtsC.size()); + for (int i = 0; i < ctrlPtsC.size(); i++) { + ctrlPts(i) = ctrlPtsC[i]; + } + //Same for knots and weights + knots("knots", knotsC.size()); + for (int i = 0; i < knotsC.size(); i++) { + knots(i) = knotsC[i]; + } + + weights("weights", weightsC.size()); + for (int i = 0; i < weightsC.size(); i++) { + weights(i) = weightsC[i]; + } + +} diff --git a/BSplineKokkos.h b/BSplineKokkos.h new file mode 100644 index 0000000..3c764ed --- /dev/null +++ b/BSplineKokkos.h @@ -0,0 +1,42 @@ +#ifndef BSPLINEKOKKOS_H +#define BSPLINEKOKKOS_H + +#include +#include +#include + +class BSplineKokkos : public Expression { +public: + //Genuinely I don't think these should be placed here. Please ask. + #ifdef KOKKOS_ENABLE_CUDA + #define MemSpace Kokkos::CudaSpace + #endif + #ifdef KOKKOS_ENABLE_HIP + #define MemSpace Kokkos::Experimental::HIPSpace + #endif + #ifndef MemSpace + #define MemSpace Kokkos::HostSpace + #endif + + using ViewVectorType = Kokkos::View; + //Constructors + BSplineKokkos(int order_p, std::vector& ctrlPts, std::vector& knots, std::vector& weight); + + //Accessors + int getOrder() const {return order;} + int getNumCtrlPts() const {return ctrlPts.extent(0);} + int getNumKnots() const {return knots.extent(0);} + double getCtrlPt(std::size_t i) const {return ctrlPts(i);} + double getKnot(std::size_t i) const {return knot(i);} + + + private: + int order; + //ADD WHAT MEMORY SPACE + ViewVectorType ctrlPts; + ViewVectorType knots; + ViewVectorType weights; + ViewVectorType ctrlPts_1stD; + ViewVectorType ctrlPts_2ndD; + +} From 420575e7679563eb3cb666b0a26caef0914b18ea Mon Sep 17 00:00:00 2001 From: hsiehh Date: Sun, 8 Mar 2026 21:40:43 -0400 Subject: [PATCH 02/73] Attempt derivative coeff function, started eval --- BSplineKokkos.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ BSplineKokkos.h | 30 ++++++++++++------------------ 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/BSplineKokkos.cpp b/BSplineKokkos.cpp index 70ada2b..33620dd 100644 --- a/BSplineKokkos.cpp +++ b/BSplineKokkos.cpp @@ -20,5 +20,45 @@ BSplineKokkos::BSplineKokkos(int orderC, std::vector& ctrlPtsC, std::vec for (int i = 0; i < weightsC.size(); i++) { weights(i) = weightsC[i]; } + //Call the calculateDerivCoeff() to populate + //1st and 2nd deriavtive views + calculateDerivCoeff(); } + +void BSplineKokkos::calculateDerivCoeff() { + //Calculate first order derivative + //Allocate space for ctrlPts_1stD + ctrlPts_1stD("ctrlPts1Derivative", ctrlPts.extent(0)-1); + for (int i = 1; i < ctrlPts.extent(0); i++) { + double delta = double(order - 1)/(knots(i+order-1)-knots(i)); + ctrlPts_1stD(i) = ((ctrlPts(i) - ctrlPts(i-1)*delta)); + + } + + //Calculate second order derivative + //Allocate space for ctrlPts_2ndD + ctrlPts_2ndD("ctrlPts2Derivative", ctrlPts.extent(0)-2); + for (int i = 0; i < ctrlPts_1stD.extent(0); i++) { + double delta = double(order - 2) / (knots(i+order-1)-knots(i+1)); + ctrlPts_2ndD(i) = ((ctrlPts_1stD(i) - ctrlPts_(i-1))*delta); + } + //TODO: find another way to verify the size of the second derivative view + +} + +dounle BSplineKokkos::eval(double x) const { + //Implemented based on the serial BSpline + //Find the interval of the 1D coordinate given + int leftKnot = order - 1; + int leftPt = 0; + while (knots(leftKnot) < x) { + leftKnot++; + leftPt++; + if (leftKnot == knots.extent(0)-1) { + break; + } + } + //START FROM HERE NEXT TIME + +} diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 3c764ed..9f32725 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -5,20 +5,11 @@ #include #include +template class BSplineKokkos : public Expression { public: - //Genuinely I don't think these should be placed here. Please ask. - #ifdef KOKKOS_ENABLE_CUDA - #define MemSpace Kokkos::CudaSpace - #endif - #ifdef KOKKOS_ENABLE_HIP - #define MemSpace Kokkos::Experimental::HIPSpace - #endif - #ifndef MemSpace - #define MemSpace Kokkos::HostSpace - #endif - - using ViewVectorType = Kokkos::View; + using MemSpace = typename ExecutionSpace::memory_space; + //Constructors BSplineKokkos(int order_p, std::vector& ctrlPts, std::vector& knots, std::vector& weight); @@ -32,11 +23,14 @@ class BSplineKokkos : public Expression { private: int order; - //ADD WHAT MEMORY SPACE - ViewVectorType ctrlPts; - ViewVectorType knots; - ViewVectorType weights; - ViewVectorType ctrlPts_1stD; - ViewVectorType ctrlPts_2ndD; + + //CtrlPts, knots, weights and their offsets + Kokkos::View ctrlPts; + Kokkos::View knots; + Kokkos::View weights; + + //The 1st and 2nd derivatives + Kokkos::View ctrlPts_1stD; + Kokkos::View ctrlPts_2ndD; } From 0f46eb0f8c065b8c4f8d01436c37a5db827bc60a Mon Sep 17 00:00:00 2001 From: Hsieh Date: Mon, 9 Mar 2026 23:43:57 -0400 Subject: [PATCH 03/73] Attempt eval function, need compilation, testing --- BSplineKokkos.cpp | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/BSplineKokkos.cpp b/BSplineKokkos.cpp index 33620dd..bf6b3e1 100644 --- a/BSplineKokkos.cpp +++ b/BSplineKokkos.cpp @@ -47,7 +47,7 @@ void BSplineKokkos::calculateDerivCoeff() { } -dounle BSplineKokkos::eval(double x) const { +double BSplineKokkos::eval(double x) const { //Implemented based on the serial BSpline //Find the interval of the 1D coordinate given int leftKnot = order - 1; @@ -59,6 +59,27 @@ dounle BSplineKokkos::eval(double x) const { break; } } - //START FROM HERE NEXT TIME + //Find the points and local knots + Kokkos::View pts("PtsView", order); + for (int i = leftKnot; i < leftKnot+order; i++) { + pts(i) = ctrlPts(i); + } + //TODO: find the size of the local knot and copy them to a view + Kokkos::View localKnots; + for (int r = 1; r <= order; r++) { + for (int i = order-1; i>= r; i--) { + double a_left = localKnots(i-1); + double a_right = localKnots(i-1); + double alpha; + if (a_right == a_left) { + alpha = 0.; + } + else { + alpha = (x-a_left)/(a_right-a_left); + } + pts(i) = (1. - alpha) * pts(i-1) + alpha*pts(i); + } + } + return pts(order-1); } From 06ae6f3ce6e92ce9206cb73873579222088e06e0 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 10 Mar 2026 00:28:10 -0400 Subject: [PATCH 04/73] Create init test for BSplineKokkos --- BSplineKokkos.cpp | 4 +++- testSplineKokkosBase.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 testSplineKokkosBase.cpp diff --git a/BSplineKokkos.cpp b/BSplineKokkos.cpp index bf6b3e1..62b7e61 100644 --- a/BSplineKokkos.cpp +++ b/BSplineKokkos.cpp @@ -22,7 +22,9 @@ BSplineKokkos::BSplineKokkos(int orderC, std::vector& ctrlPtsC, std::vec } //Call the calculateDerivCoeff() to populate //1st and 2nd deriavtive views - calculateDerivCoeff(); + + /*NOTE: UNCOMMENT THIS ONCE ALL IN FRONT ARE RESOLVED*/ + //calculateDerivCoeff(); } diff --git a/testSplineKokkosBase.cpp b/testSplineKokkosBase.cpp new file mode 100644 index 0000000..278040a --- /dev/null +++ b/testSplineKokkosBase.cpp @@ -0,0 +1,28 @@ +#include "" +#include "BSplineKokkos.h" +#include + +int main(int argc, char* argv[]) { + Kokkos::initialize(argc, argv); + + //Check for what memory space we should use + //Sticking to just cuda space or host space for now + + #ifdef KOKKOS_ENABLE_CUDA + #define MemSpace Kokkos::CudaSpace + #endif + #ifndef MemSpace + #define MemSpace Kokkos::HostSpace + #endif + + using ExecSpace = MemSpace::execution_space; + + //We will try to test with dummy data for BSplineKokkos creation + std::vector dummyCtrlPts(2.14, 3.98, 1.56, 9.10, 11.87); + std::vector dummyKnots(5.99, 8.98, 17.71, 21.1, 2.154, 9.17, 6.32); + int dOrder = 2; + std::vector dummyWeights(0.87, 0.125, 0.03); + BSplineKokkos ex1(dOrder, dummyCtrlPts, dummyKnots, dummyWeights); + + +} From 7e97698556351230c4b6a950c445669902b06e08 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 10 Mar 2026 12:53:22 -0400 Subject: [PATCH 05/73] Add BSplineKokkos executable to CMakeLists.txt --- BSplineKokkos.cpp | 2 -- CMakeLists.txt | 10 ++++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/BSplineKokkos.cpp b/BSplineKokkos.cpp index 62b7e61..7591b90 100644 --- a/BSplineKokkos.cpp +++ b/BSplineKokkos.cpp @@ -1,7 +1,5 @@ #include "BSplineKokkos.h" -#include #include -#include BSplineKokkos::BSplineKokkos(int orderC, std::vector& ctrlPtsC, std::vector& knotsC, std::vector& weightsC) { order = orderC; diff --git a/CMakeLists.txt b/CMakeLists.txt index 1109d31..c102624 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,10 @@ target_include_directories(modelGen2d PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(modelGen2d PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Quadtree/include) target_link_libraries(modelGen2d PRIVATE splineInterp Omega_h::omega_h) +#NEED TO ADD THE FILES USED FOR BSpline_Kokkos HERE +add_library(splineKokkos BSplineKokkos.cpp) +target_link_libraries(splineKokkos PRIVATE Kokkos::kokkos) + set(testDataDir ${CMAKE_CURRENT_SOURCE_DIR}/contour_test_data) if(USE_SIMMODSUITE) @@ -169,3 +173,9 @@ add_test(NAME testDiscoverTopo_L11pts set_tests_properties(testDiscoverTopo_L11pts PROPERTIES PASS_REGULAR_EXPRESSION "number of model vertices: 3") +#THE FOLLOWING IS FOR BSPLINE_KOKKOS TESTS, MAY HAVE A LOT OF ERROR + +add_executable(testSplineKokkosBase testSplineKokkosBase.cpp) +target_link_libraries(testSplineKokkosBase PRIVATE splineKokkos) +add_test(NAME dummyBSplineKokkos + COMMAND ./testSplineKokkosBase) From c07c3825a1a0eaa59fb23672199fd3d5ee150f1a Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 10 Mar 2026 23:05:45 -0400 Subject: [PATCH 06/73] Fixed some syntax error and templating issues --- BSplineKokkos.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/BSplineKokkos.cpp b/BSplineKokkos.cpp index 7591b90..e510387 100644 --- a/BSplineKokkos.cpp +++ b/BSplineKokkos.cpp @@ -1,7 +1,7 @@ #include "BSplineKokkos.h" #include - -BSplineKokkos::BSplineKokkos(int orderC, std::vector& ctrlPtsC, std::vector& knotsC, std::vector& weightsC) { +template +BSplineKokkos::BSplineKokkos(int orderC, std::vector& ctrlPtsC, std::vector& knotsC, std::vector& weightsC) { order = orderC; //Allocate appropriate view space based on the number of control points, copy the data over to view ctrlPts("ctrlPts", ctrlPtsC.size()); @@ -25,8 +25,8 @@ BSplineKokkos::BSplineKokkos(int orderC, std::vector& ctrlPtsC, std::vec //calculateDerivCoeff(); } - -void BSplineKokkos::calculateDerivCoeff() { +template +void BSplineKokkos::calculateDerivCoeff() { //Calculate first order derivative //Allocate space for ctrlPts_1stD ctrlPts_1stD("ctrlPts1Derivative", ctrlPts.extent(0)-1); @@ -41,13 +41,13 @@ void BSplineKokkos::calculateDerivCoeff() { ctrlPts_2ndD("ctrlPts2Derivative", ctrlPts.extent(0)-2); for (int i = 0; i < ctrlPts_1stD.extent(0); i++) { double delta = double(order - 2) / (knots(i+order-1)-knots(i+1)); - ctrlPts_2ndD(i) = ((ctrlPts_1stD(i) - ctrlPts_(i-1))*delta); + ctrlPts_2ndD(i) = ((ctrlPts_1stD(i) - ctrlPts_1stD(i-1))*delta); } //TODO: find another way to verify the size of the second derivative view } - -double BSplineKokkos::eval(double x) const { +template +double BSplineKokkos::eval(double x) const { //Implemented based on the serial BSpline //Find the interval of the 1D coordinate given int leftKnot = order - 1; @@ -83,3 +83,6 @@ double BSplineKokkos::eval(double x) const { return pts(order-1); } + +//Explicit instantiation of the templated class for Kokkos::serial +//template class BSplineKokkos; From a6cfa5a018afbbf58f0d9f42ab311ecd8e71e947 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 10 Mar 2026 23:07:15 -0400 Subject: [PATCH 07/73] Fix compiling error --- BSplineKokkos.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 9f32725..7c8e7a8 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -1,12 +1,13 @@ #ifndef BSPLINEKOKKOS_H #define BSPLINEKOKKOS_H + #include #include #include template -class BSplineKokkos : public Expression { +class BSplineKokkos { public: using MemSpace = typename ExecutionSpace::memory_space; @@ -18,8 +19,9 @@ class BSplineKokkos : public Expression { int getNumCtrlPts() const {return ctrlPts.extent(0);} int getNumKnots() const {return knots.extent(0);} double getCtrlPt(std::size_t i) const {return ctrlPts(i);} - double getKnot(std::size_t i) const {return knot(i);} - + double getKnot(std::size_t i) const {return knots(i);} + double eval(double x) const; + void calculateDerivCoeff(); private: int order; @@ -33,4 +35,5 @@ class BSplineKokkos : public Expression { Kokkos::View ctrlPts_1stD; Kokkos::View ctrlPts_2ndD; -} +}; +#endif From 789f6bc96cd25b63fb071d0ca5c5e078c8fd33e8 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 10 Mar 2026 23:08:01 -0400 Subject: [PATCH 08/73] Link Kokkos::kokkos to testSplineKokkosBase --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c102624..0b02254 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,6 +176,6 @@ set_tests_properties(testDiscoverTopo_L11pts PROPERTIES #THE FOLLOWING IS FOR BSPLINE_KOKKOS TESTS, MAY HAVE A LOT OF ERROR add_executable(testSplineKokkosBase testSplineKokkosBase.cpp) -target_link_libraries(testSplineKokkosBase PRIVATE splineKokkos) +target_link_libraries(testSplineKokkosBase PRIVATE splineKokkos Kokkos::kokkos) add_test(NAME dummyBSplineKokkos COMMAND ./testSplineKokkosBase) From 333c669cc0a2718d951fc6633605cd2113fbdc00 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 10 Mar 2026 23:08:50 -0400 Subject: [PATCH 09/73] Fixed vector initialization error --- testSplineKokkosBase.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/testSplineKokkosBase.cpp b/testSplineKokkosBase.cpp index 278040a..d6746a6 100644 --- a/testSplineKokkosBase.cpp +++ b/testSplineKokkosBase.cpp @@ -1,4 +1,4 @@ -#include "" +#include #include "BSplineKokkos.h" #include @@ -15,14 +15,13 @@ int main(int argc, char* argv[]) { #define MemSpace Kokkos::HostSpace #endif - using ExecSpace = MemSpace::execution_space; + using ExecutionSpace = MemSpace::execution_space; //We will try to test with dummy data for BSplineKokkos creation - std::vector dummyCtrlPts(2.14, 3.98, 1.56, 9.10, 11.87); - std::vector dummyKnots(5.99, 8.98, 17.71, 21.1, 2.154, 9.17, 6.32); + std::vector dummyCtrlPts{2.14, 3.98, 1.56, 9.10, 11.87}; + std::vector dummyKnots{5.99, 8.98, 17.71, 21.1, 2.154, 9.17, 6.32}; int dOrder = 2; - std::vector dummyWeights(0.87, 0.125, 0.03); - BSplineKokkos ex1(dOrder, dummyCtrlPts, dummyKnots, dummyWeights); - - + std::vector dummyWeights{0.87, 0.125, 0.03}; + BSplineKokkos ex1(dOrder, dummyCtrlPts, dummyKnots, dummyWeights); + Kokkos::finalize(); } From fbe50827f5e24da4854f0a2ec50fa4402ed57931 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Wed, 11 Mar 2026 17:27:15 -0400 Subject: [PATCH 10/73] Moving constructor from .cpp to .h --- BSplineKokkos.h | 121 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 112 insertions(+), 9 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 7c8e7a8..43a4a94 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -6,34 +6,137 @@ #include #include +//For the Kokkos version of the implementation, we will not be separating BSplineKokkos and BSplineKokkos2D, their respective functions will be in this file. + template class BSplineKokkos { public: using MemSpace = typename ExecutionSpace::memory_space; - //Constructors - BSplineKokkos(int order_p, std::vector& ctrlPts, std::vector& knots, std::vector& weight); + //Constructor for just 1 spline(Would this be used often?) + BSplineKokkos(int order_p, std::vector& ctrlPts_x, std::vector& ctrlPts_y, std::vector& knots_x, std::vector& knots_y, std::vector& weight_p) { + order("Orders", sizeof(int)); + order(0) = order_p; + + //Initialize control points and their offset + ctrlPts("CtrlPoints", 2*ctrlPts_x.size()); + for (int i = 0; i < ctrlPts_x.size(); i++) { + ctrlPts(i) = ctrlPts_x[i]; + } + + for (int i = 0; i < ctrlPts_y.size(); i++) { + ctrlPts(ctrlPts_x.size()+i) = ctrlPts_y[i]; + } + + cPOffset("CtrlPointsOffset", sizeof(int)*2); + cPOffset(0) = 0; //x coor start index + cPOffset(1) = ctrlPts_x.size(); //y coor start index + + //Initialize knots and their offset + knots("Knots", knots_x.size()*2); + + knotsOffset("KnotsOffset", 2*sizeof(int)); + knotsOffset(0) = 0; + knotsOffset(1) = knots_x.size(); + + for (int i = 0; i < knots_x.size(); i++) { + knots(i) = knots_x[i]; + } + for (int i = 0; i < knots_y.size(); i++) { + knots(knotsOffset(1)+i) = knots_y[i]; + } + + //Copy the weights over + weights("Weights", weights_p.size()); + for (int i = 0; i < weights_p.size(); i++) { + weights(i) = weights[i]; + } + + //Derivative coefficients + //calculateDerivCoeff(); + + } + + //Create BSpline for a vector of BSplineKokkos objects + BSplineKokkos(std::vector& splines) { + //Preallocate space for Kokkos::View + //They are fixed in size and resize is expensive + int orderSize = 0; + int ctrlPSize = 0; + int knotsSize = 0; + int cPOffSize = 0; + int kOffSize = 0; + int weightSize = 0; + + //Input the offsets + //Track space needed to allocate for ctrlPts & knots + for (int i = 0; i < splines.size(); i++) { + cPOffSize += 2*(splines[i].getNumCtrlPts()); + knotsSize += 2*(splines[i].getNumKnots()); + ctrlPSize += splines[i].getCtrlPtsSize(); + knotsSize += splines[i].getKnotsSize(); + orderSize += splines[i].getOrderSize(); + weightSize += splines[i].getWeightSize(); + } + //Pre-Allocate space for views + order("Order", orderSize); + ctrlPts("CtrlPts", ctrlPSize); + cPOffset("CtrlPtsOffset", cPOffSize); + knotsSize("Knots", knotsSize); + kOffSize("KnotsOffset", kOffSize); + weights("Weights", weightSize); + + //Populate the views with data + + } + + //Accessors - int getOrder() const {return order;} - int getNumCtrlPts() const {return ctrlPts.extent(0);} - int getNumKnots() const {return knots.extent(0);} - double getCtrlPt(std::size_t i) const {return ctrlPts(i);} - double getKnot(std::size_t i) const {return knots(i);} - double eval(double x) const; + int getOrder(int idx) const {return order(idx);} + int getOrderSize() const {return order.extent(0);} + int getNumCtrlPts() const {return ctrlPtsOffset.extent(0)/2;} + int getNumKnots() const {return knotsOffset.extent(0)/2;} + int getCtrlPtsSize() const {return ctrlPts.extent(0);} + int getKnotsSize() const {return knots.extent(0);} + int getWeightSize() const {return weights.extent(0);} + + double getCtrlPtCoor(int BspIdx, int cPIdx, char coor) const { + if (coor == 'x') { + //Find the correct offset + return ctrlPts(ctrlPtsOffset(2*BspIdx)+cPIdx); + } + else { + return ctrlPts(ctrlPtsOffset(2*BspIdx+1)+cPIdx); + } + } + double getKnotCoor(int BspIdx, int kIdx, char coor) const { + if (coor == 'x') { + return knots(knotsOffset(2*BspIdx)+kIdx); + } + else { + return knots(knotsOffset(2*BspIdx+1)+kIdx); + } + } + void calculateDerivCoeff(); private: - int order; + Kokkos::View order; //CtrlPts, knots, weights and their offsets Kokkos::View ctrlPts; + Kokkos::View cPOffset; Kokkos::View knots; + Kokkos::View knotsOffset; Kokkos::View weights; + //weight offset may be added later, not entirely sure for now //The 1st and 2nd derivatives Kokkos::View ctrlPts_1stD; + Kokkos::View cP1stDOffset; Kokkos::View ctrlPts_2ndD; + Kokkos::View cP2ndDOffset; }; #endif From 9822f38a079a90128a9d0648acde1b8741680853 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Thu, 12 Mar 2026 15:48:05 -0400 Subject: [PATCH 11/73] Moved functions use execution space to .h file --- BSplineKokkos.cpp | 49 +++------------------ BSplineKokkos.h | 107 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 91 insertions(+), 65 deletions(-) diff --git a/BSplineKokkos.cpp b/BSplineKokkos.cpp index e510387..8ba3134 100644 --- a/BSplineKokkos.cpp +++ b/BSplineKokkos.cpp @@ -1,6 +1,6 @@ #include "BSplineKokkos.h" #include -template +/*template BSplineKokkos::BSplineKokkos(int orderC, std::vector& ctrlPtsC, std::vector& knotsC, std::vector& weightsC) { order = orderC; //Allocate appropriate view space based on the number of control points, copy the data over to view @@ -21,11 +21,13 @@ BSplineKokkos::BSplineKokkos(int orderC, std::vector& ct //Call the calculateDerivCoeff() to populate //1st and 2nd deriavtive views - /*NOTE: UNCOMMENT THIS ONCE ALL IN FRONT ARE RESOLVED*/ + //NOTE: UNCOMMENT THIS ONCE ALL IN FRONT ARE RESOLVED //calculateDerivCoeff(); -} -template +}*/ + + +/*template void BSplineKokkos::calculateDerivCoeff() { //Calculate first order derivative //Allocate space for ctrlPts_1stD @@ -45,44 +47,7 @@ void BSplineKokkos::calculateDerivCoeff() { } //TODO: find another way to verify the size of the second derivative view -} -template -double BSplineKokkos::eval(double x) const { - //Implemented based on the serial BSpline - //Find the interval of the 1D coordinate given - int leftKnot = order - 1; - int leftPt = 0; - while (knots(leftKnot) < x) { - leftKnot++; - leftPt++; - if (leftKnot == knots.extent(0)-1) { - break; - } - } - //Find the points and local knots - Kokkos::View pts("PtsView", order); - for (int i = leftKnot; i < leftKnot+order; i++) { - pts(i) = ctrlPts(i); - } - //TODO: find the size of the local knot and copy them to a view - Kokkos::View localKnots; - for (int r = 1; r <= order; r++) { - for (int i = order-1; i>= r; i--) { - double a_left = localKnots(i-1); - double a_right = localKnots(i-1); - double alpha; - if (a_right == a_left) { - alpha = 0.; - } - else { - alpha = (x-a_left)/(a_right-a_left); - } - pts(i) = (1. - alpha) * pts(i-1) + alpha*pts(i); - } - } - return pts(order-1); - -} +}*/ //Explicit instantiation of the templated class for Kokkos::serial //template class BSplineKokkos; diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 43a4a94..6b2453c 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -14,38 +14,46 @@ class BSplineKokkos { using MemSpace = typename ExecutionSpace::memory_space; //Constructor for just 1 spline(Would this be used often?) - BSplineKokkos(int order_p, std::vector& ctrlPts_x, std::vector& ctrlPts_y, std::vector& knots_x, std::vector& knots_y, std::vector& weight_p) { - order("Orders", sizeof(int)); - order(0) = order_p; + BSplineKokkos(int order_p, std::vector& ctrlPts_x, std::vector& ctrlPts_y, std::vector& knots_x, std::vector& knots_y, std::vector& weights_p) { + Kokkos::View orderV("Orders", 1); + orderV(0) = order_p; + order = orderV; //Initialize control points and their offset - ctrlPts("CtrlPoints", 2*ctrlPts_x.size()); + Kokkos::View ctrlPtsV("CtrlPoints", 2*ctrlPts_x.size()); for (int i = 0; i < ctrlPts_x.size(); i++) { - ctrlPts(i) = ctrlPts_x[i]; + ctrlPtsV(i) = ctrlPts_x[i]; } for (int i = 0; i < ctrlPts_y.size(); i++) { - ctrlPts(ctrlPts_x.size()+i) = ctrlPts_y[i]; + ctrlPtsV(ctrlPts_x.size()+i) = ctrlPts_y[i]; } - cPOffset("CtrlPointsOffset", sizeof(int)*2); - cPOffset(0) = 0; //x coor start index - cPOffset(1) = ctrlPts_x.size(); //y coor start index + ctrlPts = ctrlPtsV; + Kokkos::View cPOffsetV("CtrlPointsOffset", sizeof(int)*2); + cPOffsetV(0) = 0; //x coor start index + cPOffsetV(1) = ctrlPts_x.size(); //y coor start index + + cPOffset = cPOffsetV; +/* //Initialize knots and their offset - knots("Knots", knots_x.size()*2); + Kokkos::View knotsV("Knots", knots_x.size()*2); - knotsOffset("KnotsOffset", 2*sizeof(int)); - knotsOffset(0) = 0; - knotsOffset(1) = knots_x.size(); + Kokkos::View knotsOffsetV("KnotsOffset", 2*sizeof(int)); + knotsOffsetV(0) = 0; + knotsOffsetV(1) = knots_x.size(); for (int i = 0; i < knots_x.size(); i++) { - knots(i) = knots_x[i]; + knotsV(i) = knots_x[i]; } for (int i = 0; i < knots_y.size(); i++) { - knots(knotsOffset(1)+i) = knots_y[i]; + knotsV(knotsOffset(1)+i) = knots_y[i]; } + knots = knotsV; + knotsOffset = knotsOffsetV; + //Copy the weights over weights("Weights", weights_p.size()); for (int i = 0; i < weights_p.size(); i++) { @@ -54,10 +62,10 @@ class BSplineKokkos { //Derivative coefficients //calculateDerivCoeff(); - +*/ } - //Create BSpline for a vector of BSplineKokkos objects +//Create BSpline for a vector of BSplineKokkos objects BSplineKokkos(std::vector& splines) { //Preallocate space for Kokkos::View //They are fixed in size and resize is expensive @@ -82,8 +90,8 @@ class BSplineKokkos { order("Order", orderSize); ctrlPts("CtrlPts", ctrlPSize); cPOffset("CtrlPtsOffset", cPOffSize); - knotsSize("Knots", knotsSize); - kOffSize("KnotsOffset", kOffSize); + knots("Knots", knotsSize); + knotsOffset("KnotsOffset", kOffSize); weights("Weights", weightSize); //Populate the views with data @@ -95,7 +103,7 @@ class BSplineKokkos { //Accessors int getOrder(int idx) const {return order(idx);} int getOrderSize() const {return order.extent(0);} - int getNumCtrlPts() const {return ctrlPtsOffset.extent(0)/2;} + int getNumCtrlPts() const {return cPOffset.extent(0)/2;} int getNumKnots() const {return knotsOffset.extent(0)/2;} int getCtrlPtsSize() const {return ctrlPts.extent(0);} int getKnotsSize() const {return knots.extent(0);} @@ -104,10 +112,10 @@ class BSplineKokkos { double getCtrlPtCoor(int BspIdx, int cPIdx, char coor) const { if (coor == 'x') { //Find the correct offset - return ctrlPts(ctrlPtsOffset(2*BspIdx)+cPIdx); + return ctrlPts(cPOffset(2*BspIdx)+cPIdx); } else { - return ctrlPts(ctrlPtsOffset(2*BspIdx+1)+cPIdx); + return ctrlPts(cPOffset(2*BspIdx+1)+cPIdx); } } double getKnotCoor(int BspIdx, int kIdx, char coor) const { @@ -119,9 +127,62 @@ class BSplineKokkos { } } - void calculateDerivCoeff(); + void calculateDerivCoeff() { + //Moved here from the .cpp file since it uses + //Calculate first order derivative + //Allocate the space + ctrlPts_1stD("ctrlPts1Derivative", ctrlPts.extent(0)-cPOffset.extent(0)); + cP1stDOffset("ctrlPts1DerivativeOffset", cPOffset.extent(0)); + ctrlPts_2ndD("ctrlPts1Derivative", ctrlPts.extent(0)-2*(cPOffset.extent(0))); + cP2ndDOffset("ctrlPts2DerivativeOffset", cPOffset.extent(0)); + cP2ndDOffset(0) = 0; + + //Adjust the offset to include be 1 & 2 less than the ctrlPtsOffset + cP1stDOffset(0) = 0; + for (int i = 1; i < cPOffset.extent(0); i++) { + cP1stDOffset(i) = cPOffset(i)-1; + cP2ndDOffset(i) = cPOffset(i)-2; + } + + //We need to partition the x and y while we calculate the coefficient + int idx = 1; + int oidx = 0; + for (int i = 1; i < cPOffset(cPOffset.extend(0)-2); i++) { + if (i == cPOffset(idx)) { + //Do not calculate, delta will be based on both x and y + idx++; + if (idx % 2 == 0) { + oidx++; + } + continue; + } + double delta = double(order(oidx) - 1)/(knots(i+order(oidx)-1)-knots(i)); + ctrlPts_1stD(i-1) = ((ctrlPts(i) - ctrlPts(i-1)*delta)); + } + + //Calculate second order derivative + ctrlPts_2ndD("ctrlPts1Derivative", ctrlPts.extent(0)-2*(cPOffset.extent(0))); + cP2ndDOffset("ctrlPts2DerivativeOffset", cPOffset.extent(0)); + cP2ndDOffset(0) = 0; + + idx = 1; + oidx = 0; + + for (int i = 1; i < ctrlPts_1stD.extent(0); i++) { + if (i == cP1stDOffset(idx)) { + idx++; + if (idx %2 == 0) { + oidx++; + } + continue; + } + double delta = double((order(oidx)-2))/(knots(i+order(oidx)-1)-knots(i+1)); + ctrlPts_2ndD(i-1) = ctrlPts_1stD(i) - ctrlPts_1stD(i-1)*delta; + } + } private: + Kokkos::View order; //CtrlPts, knots, weights and their offsets From f87d67aad203265e92dddafe5138c16380cdb9ac Mon Sep 17 00:00:00 2001 From: Hsieh Date: Thu, 12 Mar 2026 15:48:52 -0400 Subject: [PATCH 12/73] Modified test case to suit the 2D structure --- testSplineKokkosBase.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/testSplineKokkosBase.cpp b/testSplineKokkosBase.cpp index d6746a6..e35c248 100644 --- a/testSplineKokkosBase.cpp +++ b/testSplineKokkosBase.cpp @@ -18,10 +18,13 @@ int main(int argc, char* argv[]) { using ExecutionSpace = MemSpace::execution_space; //We will try to test with dummy data for BSplineKokkos creation - std::vector dummyCtrlPts{2.14, 3.98, 1.56, 9.10, 11.87}; - std::vector dummyKnots{5.99, 8.98, 17.71, 21.1, 2.154, 9.17, 6.32}; + std::vector dummyCtrlPtsX{2.14, 3.98, 1.56, 9.10, 11.87}; + + std::vector dummyCtrlPtsY{7.928, 12.18, 9.17, 6.67, 12.78}; + std::vector dummyKnotsX{5.99, 8.98, 17.71, 21.1, 2.154, 9.17, 6.32}; + std::vector dummyKnotsY{2.85, 1.16, 0.82, 1.89, 9.82, 12.0, 7.19}; int dOrder = 2; std::vector dummyWeights{0.87, 0.125, 0.03}; - BSplineKokkos ex1(dOrder, dummyCtrlPts, dummyKnots, dummyWeights); + BSplineKokkos ex1(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); Kokkos::finalize(); } From 004e5ee81bbee7566ca1fdf1d114b22610e591a9 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Thu, 12 Mar 2026 18:07:44 -0400 Subject: [PATCH 13/73] Fixed 1st, 2nd derivative coef function --- BSplineKokkos.h | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 6b2453c..19c3f2c 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -36,7 +36,7 @@ class BSplineKokkos { cPOffsetV(1) = ctrlPts_x.size(); //y coor start index cPOffset = cPOffsetV; -/* + //Initialize knots and their offset Kokkos::View knotsV("Knots", knots_x.size()*2); @@ -55,14 +55,15 @@ class BSplineKokkos { knotsOffset = knotsOffsetV; //Copy the weights over - weights("Weights", weights_p.size()); + Kokkos::View weightsV("Weights", weights_p.size()); for (int i = 0; i < weights_p.size(); i++) { - weights(i) = weights[i]; + weightsV(i) = weights[i]; } + weights = weightsV; //Derivative coefficients //calculateDerivCoeff(); -*/ + } //Create BSpline for a vector of BSplineKokkos objects @@ -131,17 +132,17 @@ class BSplineKokkos { //Moved here from the .cpp file since it uses //Calculate first order derivative //Allocate the space - ctrlPts_1stD("ctrlPts1Derivative", ctrlPts.extent(0)-cPOffset.extent(0)); - cP1stDOffset("ctrlPts1DerivativeOffset", cPOffset.extent(0)); - ctrlPts_2ndD("ctrlPts1Derivative", ctrlPts.extent(0)-2*(cPOffset.extent(0))); - cP2ndDOffset("ctrlPts2DerivativeOffset", cPOffset.extent(0)); - cP2ndDOffset(0) = 0; + Kokkos::View ctrlPts_1stDV("ctrlPts1Derivative", ctrlPts.extent(0)-cPOffset.extent(0)); + Kokkos::View cP1stDOffsetV("ctrlPts1DerivativeOffset", cPOffset.extent(0)); + ctrlPts_2ndD("ctrlPts2Derivative", ctrlPts.extent(0)-2*(cPOffset.extent(0))); + Kokkos::View cP2ndDOffsetV("ctrlPts2DerivativeOffset", cPOffset.extent(0)); + cP2ndDOffsetV(0) = 0; //Adjust the offset to include be 1 & 2 less than the ctrlPtsOffset - cP1stDOffset(0) = 0; + cP1stDOffsetV(0) = 0; for (int i = 1; i < cPOffset.extent(0); i++) { - cP1stDOffset(i) = cPOffset(i)-1; - cP2ndDOffset(i) = cPOffset(i)-2; + cP1stDOffsetV(i) = cPOffset(i)-1; + cP2ndDOffsetV(i) = cPOffset(i)-2; } //We need to partition the x and y while we calculate the coefficient @@ -157,19 +158,17 @@ class BSplineKokkos { continue; } double delta = double(order(oidx) - 1)/(knots(i+order(oidx)-1)-knots(i)); - ctrlPts_1stD(i-1) = ((ctrlPts(i) - ctrlPts(i-1)*delta)); + ctrlPts_1stDV(i-1) = ((ctrlPts(i) - ctrlPts(i-1)*delta)); } //Calculate second order derivative - ctrlPts_2ndD("ctrlPts1Derivative", ctrlPts.extent(0)-2*(cPOffset.extent(0))); - cP2ndDOffset("ctrlPts2DerivativeOffset", cPOffset.extent(0)); - cP2ndDOffset(0) = 0; + Kokkos::View ctrlPts_2ndDV("ctrlPts1Derivative", ctrlPts.extent(0)-2*(cPOffset.extent(0))); idx = 1; oidx = 0; - for (int i = 1; i < ctrlPts_1stD.extent(0); i++) { - if (i == cP1stDOffset(idx)) { + for (int i = 1; i < ctrlPts_1stDV.extent(0); i++) { + if (i == cP1stDOffsetV(idx)) { idx++; if (idx %2 == 0) { oidx++; @@ -177,8 +176,12 @@ class BSplineKokkos { continue; } double delta = double((order(oidx)-2))/(knots(i+order(oidx)-1)-knots(i+1)); - ctrlPts_2ndD(i-1) = ctrlPts_1stD(i) - ctrlPts_1stD(i-1)*delta; + ctrlPts_2ndDV(i-1) = ctrlPts_1stDV(i) - ctrlPts_1stDV(i-1)*delta; } + ctrlPts_2ndD = ctrlPts_2ndDV; + ctrlPts_1stD = ctrlPts_1stDV; + cP1stDOffset = cP1stDOffsetV; + cP2ndDOffset = cP2ndDOffsetV; } private: From 1b0c5226863b194821e9d095709600cd68684adf Mon Sep 17 00:00:00 2001 From: Hsieh Date: Thu, 12 Mar 2026 19:11:44 -0400 Subject: [PATCH 14/73] Added constructor from a vector of kokkos splines --- BSplineKokkos.h | 77 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 8 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 19c3f2c..449e90a 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -88,22 +88,83 @@ class BSplineKokkos { weightSize += splines[i].getWeightSize(); } //Pre-Allocate space for views - order("Order", orderSize); - ctrlPts("CtrlPts", ctrlPSize); - cPOffset("CtrlPtsOffset", cPOffSize); - knots("Knots", knotsSize); - knotsOffset("KnotsOffset", kOffSize); - weights("Weights", weightSize); + Kokkos::View orderV ("Order", orderSize); + Kokkos::View ctrlPtsV ("CtrlPts", ctrlPSize); + Kokkos::View cPOffsetV ("CtrlPtsOffset", cPOffSize); + Kokkos::View knotsV("Knots", knotsSize); + Kokkos::View knotsOffsetV ("KnotsOffset", kOffSize); + Kokkos::View weightsV("Weights", weightSize); + int oidx = 0; + int cPidx = 0; + int cOidx = 0; + int kidx = 0; + int kOidx = 0; + int widx = 0; //Populate the views with data + int lastOffset = 0; + + for (int i = 0; i < splines.size(); i++) { + Kokkos::View intView = splines[i].getOrder(); + //Populate order + for (int j = 0; j < intView.extent(0); j++) { + orderV(oidx+j)= intView(j); + } + oidx += intView.extent(0); + //Populate ctrlpts offset + //Offset the offset by the last offset in the view + intView = splines[i].getCPOffset(); + for (int j = 0; j < intView.extent(0); j++) { + cPOffsetV(cOidx+j) = intView(j)+lastOffset; + } + cOidx += intView.extent(0); + lastOffset = intView(intView.extent(0)-1)+(intView(intView.extent(0)-1) - intView(intView.extent(0)-2)); + //Populate knots offset + //Offset the offset by the last offset in the view + intView = splines[i].getKnotsOffset(); + for (int j = 0; j < intView.extent(0); j++) { + knotsOffsetV(kOidx+j) = intView(j)+lastOffset; + } + kOidx += intView.extent(0); + lastOffset = intView(intView.extent(0)-1)+(intView(intView.extent(0)-1) - intView(intView.extent(0)-2)); + //Populate ctrlpts + Kokkos::View doubleView = splines[i].getCtrlPts(); + for (int j = 0; j < doubleView.extent(0); j++) { + ctrlPtsV(cPidx+j) = doubleView(j); + } + cPidx += doubleView.extent(0); + //Populate knots + doubleView = splines[i].getKnots(); + for (int j = 0; j < doubleView.extent(0); j++) { + knotsV(kidx+j) = doubleView(j); + } + kidx += doubleView.extent(0); + //Populate the weights + doubleView = splines[i].getWeights(); + for (int j = 0; j < doubleView.extent(0); j++) { + weightsV(widx+j) = doubleView(j); + } + widx += doubleView.extent(0); + } + order = orderV; + knots = knotsV; + ctrlPts = ctrlPtsV; + weights = weightsV; + cPOffset = cPOffsetV; + knotsOffset = knotsOffsetV; } //Accessors - int getOrder(int idx) const {return order(idx);} - int getOrderSize() const {return order.extent(0);} + Kokkos::View getOrder() const {return order;} + Kokkos::View getCtrlPts() const {return ctrlPts;} + Kokkos::View getKnots() const {return knots;} + Kokkos::View getWeights() const {return weights;} + Kokkos::View getCPOffset() const {return cPOffset;} + Kokkos::View getKnotsOffset() const {return knotsOffset;} + int getNumCtrlPts() const {return cPOffset.extent(0)/2;} int getNumKnots() const {return knotsOffset.extent(0)/2;} int getCtrlPtsSize() const {return ctrlPts.extent(0);} From 603aee717b78389e5c2eff6037c72df9c6c5f76a Mon Sep 17 00:00:00 2001 From: Hsieh Date: Thu, 12 Mar 2026 19:38:18 -0400 Subject: [PATCH 15/73] fixed 1 spline initialization and test --- BSplineKokkos.h | 26 ++++++++++++++++--------- testSplineKokkosBase.cpp | 41 ++++++++++++++++++++++++---------------- 2 files changed, 42 insertions(+), 25 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 449e90a..8803833 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -5,6 +5,7 @@ #include #include #include +#include //For the Kokkos version of the implementation, we will not be separating BSplineKokkos and BSplineKokkos2D, their respective functions will be in this file. @@ -18,7 +19,7 @@ class BSplineKokkos { Kokkos::View orderV("Orders", 1); orderV(0) = order_p; order = orderV; - + std::cout << "Order view added" << std::endl; //Initialize control points and their offset Kokkos::View ctrlPtsV("CtrlPoints", 2*ctrlPts_x.size()); for (int i = 0; i < ctrlPts_x.size(); i++) { @@ -28,19 +29,22 @@ class BSplineKokkos { for (int i = 0; i < ctrlPts_y.size(); i++) { ctrlPtsV(ctrlPts_x.size()+i) = ctrlPts_y[i]; } + std::cout << "ctrlPts initialized" << std::endl; ctrlPts = ctrlPtsV; - Kokkos::View cPOffsetV("CtrlPointsOffset", sizeof(int)*2); + Kokkos::View cPOffsetV("CtrlPointsOffset", 2); cPOffsetV(0) = 0; //x coor start index cPOffsetV(1) = ctrlPts_x.size(); //y coor start index cPOffset = cPOffsetV; + std::cout << "cp offset initialized" << std::endl; + //Initialize knots and their offset Kokkos::View knotsV("Knots", knots_x.size()*2); - Kokkos::View knotsOffsetV("KnotsOffset", 2*sizeof(int)); + Kokkos::View knotsOffsetV("KnotsOffset", 2); knotsOffsetV(0) = 0; knotsOffsetV(1) = knots_x.size(); @@ -48,21 +52,26 @@ class BSplineKokkos { knotsV(i) = knots_x[i]; } for (int i = 0; i < knots_y.size(); i++) { - knotsV(knotsOffset(1)+i) = knots_y[i]; + knotsV(knotsOffsetV(1)+i) = knots_y[i]; } knots = knotsV; knotsOffset = knotsOffsetV; + std::cout << "knots initialized" << std::endl; + std::cout << "knots offset initialized" << std::endl; + //Copy the weights over Kokkos::View weightsV("Weights", weights_p.size()); for (int i = 0; i < weights_p.size(); i++) { - weightsV(i) = weights[i]; + weightsV(i) = weights_p[i]; } weights = weightsV; + std::cout << "weights initialized" << std::endl; + //Derivative coefficients - //calculateDerivCoeff(); + calculateDerivCoeff(); } @@ -195,7 +204,6 @@ class BSplineKokkos { //Allocate the space Kokkos::View ctrlPts_1stDV("ctrlPts1Derivative", ctrlPts.extent(0)-cPOffset.extent(0)); Kokkos::View cP1stDOffsetV("ctrlPts1DerivativeOffset", cPOffset.extent(0)); - ctrlPts_2ndD("ctrlPts2Derivative", ctrlPts.extent(0)-2*(cPOffset.extent(0))); Kokkos::View cP2ndDOffsetV("ctrlPts2DerivativeOffset", cPOffset.extent(0)); cP2ndDOffsetV(0) = 0; @@ -209,7 +217,7 @@ class BSplineKokkos { //We need to partition the x and y while we calculate the coefficient int idx = 1; int oidx = 0; - for (int i = 1; i < cPOffset(cPOffset.extend(0)-2); i++) { + for (int i = 1; i < cPOffset(cPOffset.extent(0)-2); i++) { if (i == cPOffset(idx)) { //Do not calculate, delta will be based on both x and y idx++; @@ -223,7 +231,7 @@ class BSplineKokkos { } //Calculate second order derivative - Kokkos::View ctrlPts_2ndDV("ctrlPts1Derivative", ctrlPts.extent(0)-2*(cPOffset.extent(0))); + Kokkos::View ctrlPts_2ndDV("ctrlPts2Derivative", ctrlPts.extent(0)-2*(cPOffset.extent(0))); idx = 1; oidx = 0; diff --git a/testSplineKokkosBase.cpp b/testSplineKokkosBase.cpp index e35c248..f1283b6 100644 --- a/testSplineKokkosBase.cpp +++ b/testSplineKokkosBase.cpp @@ -1,30 +1,39 @@ #include #include "BSplineKokkos.h" #include +#include int main(int argc, char* argv[]) { Kokkos::initialize(argc, argv); - + { //Check for what memory space we should use //Sticking to just cuda space or host space for now - #ifdef KOKKOS_ENABLE_CUDA - #define MemSpace Kokkos::CudaSpace - #endif - #ifndef MemSpace - #define MemSpace Kokkos::HostSpace - #endif + #ifdef KOKKOS_ENABLE_CUDA + #define MemSpace Kokkos::CudaSpace + #endif + #ifndef MemSpace + #define MemSpace Kokkos::HostSpace + #endif + + using ExecutionSpace = MemSpace::execution_space; + + //We will try to test with dummy data for BSplineKokkos creation + std::vector dummyCtrlPtsX{2.14, 3.98, 1.56, 9.10, 11.87}; - using ExecutionSpace = MemSpace::execution_space; + std::vector dummyCtrlPtsY{7.928, 12.18, 9.17, 6.67, 12.78}; + std::vector dummyKnotsX{5.99, 8.98, 17.71, 21.1, 2.154, 9.17, 6.32}; + std::vector dummyKnotsY{2.85, 1.16, 0.82, 1.89, 9.82, 12.0, 7.19}; + int dOrder = 2; + std::vector dummyWeights{0.87, 0.125, 0.03}; + //Initialize 1 Kokkos Spline + BSplineKokkos ex1(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); - //We will try to test with dummy data for BSplineKokkos creation - std::vector dummyCtrlPtsX{2.14, 3.98, 1.56, 9.10, 11.87}; + //Check if we actually initialized with correct values + std::cout << "Number of ctrlPts: " << ex1.getNumCtrlPts() << std::endl; + std::cout << "Number of knots: " << ex1.getNumKnots() << std::endl; + std::cout << "Number of weights: " << ex1.getWeightSize() << std::endl; - std::vector dummyCtrlPtsY{7.928, 12.18, 9.17, 6.67, 12.78}; - std::vector dummyKnotsX{5.99, 8.98, 17.71, 21.1, 2.154, 9.17, 6.32}; - std::vector dummyKnotsY{2.85, 1.16, 0.82, 1.89, 9.82, 12.0, 7.19}; - int dOrder = 2; - std::vector dummyWeights{0.87, 0.125, 0.03}; - BSplineKokkos ex1(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); + } Kokkos::finalize(); } From 09b8b83f01810d6e12202dcaaadbb0dce0ea41e6 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Fri, 13 Mar 2026 18:58:53 -0400 Subject: [PATCH 16/73] Multispline constructor, offset problem in progress --- BSplineKokkos.h | 3 +- testSplineKokkosBase.cpp | 66 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 8803833..42be2c1 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -93,7 +93,7 @@ class BSplineKokkos { knotsSize += 2*(splines[i].getNumKnots()); ctrlPSize += splines[i].getCtrlPtsSize(); knotsSize += splines[i].getKnotsSize(); - orderSize += splines[i].getOrderSize(); + orderSize += splines[i].getOrder().extent(0); weightSize += splines[i].getWeightSize(); } //Pre-Allocate space for views @@ -128,6 +128,7 @@ class BSplineKokkos { } cOidx += intView.extent(0); lastOffset = intView(intView.extent(0)-1)+(intView(intView.extent(0)-1) - intView(intView.extent(0)-2)); + std::cout << "LastOffset: " << lastOffset << std::endl; //Populate knots offset //Offset the offset by the last offset in the view intView = splines[i].getKnotsOffset(); diff --git a/testSplineKokkosBase.cpp b/testSplineKokkosBase.cpp index f1283b6..f2919d6 100644 --- a/testSplineKokkosBase.cpp +++ b/testSplineKokkosBase.cpp @@ -3,6 +3,37 @@ #include #include +template +void printDView(Kokkos::View& dView) { + for (int i = 0; i < dView.extent(0); i++) { + std::cout << dView(i) << std::endl; + } +} + +template +void printIView(Kokkos::View& iView) { + for (int i = 0; i < iView.extent(0); i++) { + std::cout << iView(i) << std::endl; + } +} + +template +void printSpline(BSplineKokkos spline) { + std::cout << "Spline content" << std::endl; + Kokkos::View dView = spline.getCtrlPts(); + std::cout << "CtrlPts" << std::endl; + printDView(dView); + Kokkos::View iView = spline.getCPOffset(); + std::cout << "CtrlPts Offset" << std::endl; + printIView(iView); + dView = spline.getKnots(); + std::cout << "Knots" << std::endl; + printDView(dView); + iView = spline.getKnotsOffset(); + std::cout << "Knots Offset" << std::endl; + printIView(iView); +} + int main(int argc, char* argv[]) { Kokkos::initialize(argc, argv); { @@ -30,10 +61,39 @@ int main(int argc, char* argv[]) { BSplineKokkos ex1(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); //Check if we actually initialized with correct values - std::cout << "Number of ctrlPts: " << ex1.getNumCtrlPts() << std::endl; - std::cout << "Number of knots: " << ex1.getNumKnots() << std::endl; - std::cout << "Number of weights: " << ex1.getWeightSize() << std::endl; + std::cout << "ex1" << std::endl; + printSpline(ex1); + std::vector> splineList; + splineList.push_back(ex1); + + //Test constructor that takes in multiple BSplineKokkos objects + dummyCtrlPtsX.assign({1.20, 12.91, 7.11}); + dummyCtrlPtsY.assign({3.31, 7.89, 9.12}); + dummyKnotsX.assign({2.18, 5.56, 3.18, 16.15}); + dummyKnotsY.assign({1.971,4.12, 8.192, 12.11}); + dOrder = 3; + dummyWeights.assign({0.19, 0.27}); + BSplineKokkos ex2(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); + splineList.push_back(ex2); + std::cout << "ex2" << std::endl; + printSpline(ex2); + + dummyCtrlPtsX.assign({18.29, 12.12, 5.92, 7.182, 1.16}); + dummyCtrlPtsY.assign({4.72, 5.78, 9.12, 1.29, 10.2}); + dummyKnotsX.assign({4.34, 29.3, 18.7}); + dummyKnotsY.assign({19.12, 10.21, 12.78}); + dOrder = 5; + dummyWeights.assign({0.12, 0.182, 0.98, 0.05}); + BSplineKokkos ex3(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); + splineList.push_back(ex3); + std::cout << "ex3" << std::endl; + printSpline(ex3); + + BSplineKokkos fromList(splineList); + std::cout << "Spline created from list of splines" << std::endl; + printSpline(fromList); + } Kokkos::finalize(); } From 8030c592e951e32fd3bd44acee89667ff5b4001f Mon Sep 17 00:00:00 2001 From: Hsieh Date: Mon, 16 Mar 2026 09:46:36 -0400 Subject: [PATCH 17/73] Fixed ctrlpts, knots offset error --- BSplineKokkos.h | 26 ++++++++++---------------- testSplineKokkosBase.cpp | 1 + 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 42be2c1..1fac18a 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -29,7 +29,6 @@ class BSplineKokkos { for (int i = 0; i < ctrlPts_y.size(); i++) { ctrlPtsV(ctrlPts_x.size()+i) = ctrlPts_y[i]; } - std::cout << "ctrlPts initialized" << std::endl; ctrlPts = ctrlPtsV; @@ -39,8 +38,6 @@ class BSplineKokkos { cPOffset = cPOffsetV; - std::cout << "cp offset initialized" << std::endl; - //Initialize knots and their offset Kokkos::View knotsV("Knots", knots_x.size()*2); @@ -58,9 +55,6 @@ class BSplineKokkos { knots = knotsV; knotsOffset = knotsOffsetV; - std::cout << "knots initialized" << std::endl; - std::cout << "knots offset initialized" << std::endl; - //Copy the weights over Kokkos::View weightsV("Weights", weights_p.size()); for (int i = 0; i < weights_p.size(); i++) { @@ -68,8 +62,6 @@ class BSplineKokkos { } weights = weightsV; - std::cout << "weights initialized" << std::endl; - //Derivative coefficients calculateDerivCoeff(); @@ -90,7 +82,7 @@ class BSplineKokkos { //Track space needed to allocate for ctrlPts & knots for (int i = 0; i < splines.size(); i++) { cPOffSize += 2*(splines[i].getNumCtrlPts()); - knotsSize += 2*(splines[i].getNumKnots()); + kOffSize += 2*(splines[i].getNumKnots()); ctrlPSize += splines[i].getCtrlPtsSize(); knotsSize += splines[i].getKnotsSize(); orderSize += splines[i].getOrder().extent(0); @@ -103,7 +95,8 @@ class BSplineKokkos { Kokkos::View knotsV("Knots", knotsSize); Kokkos::View knotsOffsetV ("KnotsOffset", kOffSize); Kokkos::View weightsV("Weights", weightSize); - + + int oidx = 0; int cPidx = 0; int cOidx = 0; @@ -111,7 +104,8 @@ class BSplineKokkos { int kOidx = 0; int widx = 0; //Populate the views with data - int lastOffset = 0; + int cpLast = 0; + int kLast = 0; for (int i = 0; i < splines.size(); i++) { Kokkos::View intView = splines[i].getOrder(); @@ -124,19 +118,19 @@ class BSplineKokkos { //Offset the offset by the last offset in the view intView = splines[i].getCPOffset(); for (int j = 0; j < intView.extent(0); j++) { - cPOffsetV(cOidx+j) = intView(j)+lastOffset; + cPOffsetV(cOidx+j) = intView(j)+cpLast; } cOidx += intView.extent(0); - lastOffset = intView(intView.extent(0)-1)+(intView(intView.extent(0)-1) - intView(intView.extent(0)-2)); - std::cout << "LastOffset: " << lastOffset << std::endl; + cpLast = cPOffsetV(cOidx-1)+(cPOffsetV(cOidx-1) - cPOffsetV(cOidx-2)); //Populate knots offset //Offset the offset by the last offset in the view intView = splines[i].getKnotsOffset(); for (int j = 0; j < intView.extent(0); j++) { - knotsOffsetV(kOidx+j) = intView(j)+lastOffset; + knotsOffsetV(kOidx+j) = intView(j)+kLast; } kOidx += intView.extent(0); - lastOffset = intView(intView.extent(0)-1)+(intView(intView.extent(0)-1) - intView(intView.extent(0)-2)); + kLast = knotsOffsetV(kOidx-1)+(knotsOffsetV(kOidx-1) - knotsOffsetV(kOidx-2)); + //Populate ctrlpts Kokkos::View doubleView = splines[i].getCtrlPts(); for (int j = 0; j < doubleView.extent(0); j++) { diff --git a/testSplineKokkosBase.cpp b/testSplineKokkosBase.cpp index f2919d6..40dda0d 100644 --- a/testSplineKokkosBase.cpp +++ b/testSplineKokkosBase.cpp @@ -84,6 +84,7 @@ int main(int argc, char* argv[]) { dummyKnotsY.assign({19.12, 10.21, 12.78}); dOrder = 5; dummyWeights.assign({0.12, 0.182, 0.98, 0.05}); + std::cout << "\t\tSTART OF MULTISPLINE CREATION" << std::endl; BSplineKokkos ex3(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); splineList.push_back(ex3); std::cout << "ex3" << std::endl; From 79b1947b720824e86d686a3837a3f0babb180daa Mon Sep 17 00:00:00 2001 From: Hsieh Date: Mon, 16 Mar 2026 22:11:37 -0400 Subject: [PATCH 18/73] First attempt on eval1stDerivative --- BSplineKokkos.h | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 1fac18a..de55242 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -41,6 +41,7 @@ class BSplineKokkos { //Initialize knots and their offset Kokkos::View knotsV("Knots", knots_x.size()*2); + Kokkos::View knotsOffsetV("KnotsOffset", 2); knotsOffsetV(0) = 0; knotsOffsetV(1) = knots_x.size(); @@ -159,6 +160,62 @@ class BSplineKokkos { } + double evalFirstDeriv(double x, int splineo, char coor) const { + //Find the order based on the spline number given + int lKnot = order(splineo)-1; + //Find the range that contains this spline + //Need to make sure it is within the range of this spline + int leftPt; + int bound; + if (coor == 'x') { + //We are calculating the x component + leftPt = knotsOffset(2*splineo); + bound = knotsOffset(2*splineo+1); + } + else { + leftPt = knotsOffset(2*splineo+1); + bound = knotsOffset(2*(splineo+1)); + } + //Search within this range + while (knots(leftPt+1) < x && leftPt < bound) { + lKnot++; + leftPt++; + } + + int order_t = order(splineo)-1; + + //Copy to view; + int idx = 0; + Kokkos::View pts(order_t); + for (int i = leftPt; i < leftPt+order_t; i++) { + pts(idx) = ctrlPts_1stD(i); + idx++; + } + idx = 0; + Kokkos::View localKnots(2*order_t-2); + for (int i = lKnot-order_t+2; i < lKnot+order_t+1; i++) { + localKnots(idx) = knots(i); + } + + Kokkos::parallel_for("1st derivative loop", order_t, KOKKOS_LAMBDA(int r) { + for (int i = order_t-1; i >= r+1; i--) { + double aLeft = localKnots(i-1); + double aRight = localKnots(i+order_t-(r+1)-1); + double alpha; + if (aLeft == aRight) { + alpha = 0.; + } + else { + alpha = (x-aLeft)/(aRight-aLeft); + } + pts(i) = (1. - alpha) * pts(i-1)+alpha*pts(i); + } + }); + return pts(order_t-1); + } + + + //Accessors @@ -174,6 +231,7 @@ class BSplineKokkos { int getCtrlPtsSize() const {return ctrlPts.extent(0);} int getKnotsSize() const {return knots.extent(0);} int getWeightSize() const {return weights.extent(0);} + int getOrderSize() const {return order.extent(0);} double getCtrlPtCoor(int BspIdx, int cPIdx, char coor) const { if (coor == 'x') { From defbba26a6781ae0753ff0ba138b60c079e29859 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Mon, 16 Mar 2026 23:00:17 -0400 Subject: [PATCH 19/73] Still debugging derivative coef calculation error --- BSplineKokkos.h | 35 +++++++++++++++++++++++++++++++---- testSplineKokkosBase.cpp | 7 +++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index de55242..7abec05 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -65,9 +65,19 @@ class BSplineKokkos { //Derivative coefficients calculateDerivCoeff(); + std::cout << "1st derivative" << std::endl; + for (int i = 0; i < ctrlPts_1stD.extent(0); i++){ std::cout << ctrlPts_1stD(i) << std::endl; + } + std::cout << "2nd derivative" << std::endl; + for (int i = 0; i < ctrlPts_2ndD.extent(0); i++){ + std::cout << ctrlPts_2ndD.extent(0) << std::endl; + } + std::cout<<"constructor end" << std::endl; } + + //Create BSpline for a vector of BSplineKokkos objects BSplineKokkos(std::vector& splines) { //Preallocate space for Kokkos::View @@ -157,12 +167,16 @@ class BSplineKokkos { weights = weightsV; cPOffset = cPOffsetV; knotsOffset = knotsOffsetV; + calculateDerivCoeff(); } double evalFirstDeriv(double x, int splineo, char coor) const { //Find the order based on the spline number given int lKnot = order(splineo)-1; + std::cout << "lKnot: " << lKnot << std::endl; + std::cout << "Order: " << order(splineo) < pts(order_t); + Kokkos::View pts("pts", order_t); for (int i = leftPt; i < leftPt+order_t; i++) { + std::cout << i << "|" << ctrlPts_1stD(i) << std::endl; pts(idx) = ctrlPts_1stD(i); idx++; } idx = 0; - Kokkos::View localKnots(2*order_t-2); + Kokkos::View localKnots("local knots", 2*order_t-2); for (int i = lKnot-order_t+2; i < lKnot+order_t+1; i++) { localKnots(idx) = knots(i); } @@ -225,6 +246,9 @@ class BSplineKokkos { Kokkos::View getWeights() const {return weights;} Kokkos::View getCPOffset() const {return cPOffset;} Kokkos::View getKnotsOffset() const {return knotsOffset;} + Kokkos::View get1stD() const {return ctrlPts_1stD;} + Kokkos::View get2ndD() const {return ctrlPts_2ndD;} + int getNumCtrlPts() const {return cPOffset.extent(0)/2;} int getNumKnots() const {return knotsOffset.extent(0)/2;} @@ -255,7 +279,7 @@ class BSplineKokkos { //Moved here from the .cpp file since it uses //Calculate first order derivative //Allocate the space - Kokkos::View ctrlPts_1stDV("ctrlPts1Derivative", ctrlPts.extent(0)-cPOffset.extent(0)); + Kokkos::View ctrlPts_1stDV("ctrlPts1Derivative", ctrlPts.extent(0)-(cPOffset.extent(0)/2)); Kokkos::View cP1stDOffsetV("ctrlPts1DerivativeOffset", cPOffset.extent(0)); Kokkos::View cP2ndDOffsetV("ctrlPts2DerivativeOffset", cPOffset.extent(0)); cP2ndDOffsetV(0) = 0; @@ -270,6 +294,8 @@ class BSplineKokkos { //We need to partition the x and y while we calculate the coefficient int idx = 1; int oidx = 0; + + std::cout << cPOffset(cPOffset.extent(0)-2) << std::endl; for (int i = 1; i < cPOffset(cPOffset.extent(0)-2); i++) { if (i == cPOffset(idx)) { //Do not calculate, delta will be based on both x and y @@ -280,11 +306,12 @@ class BSplineKokkos { continue; } double delta = double(order(oidx) - 1)/(knots(i+order(oidx)-1)-knots(i)); + std::cout << "delta: " << delta << std::endl; ctrlPts_1stDV(i-1) = ((ctrlPts(i) - ctrlPts(i-1)*delta)); } //Calculate second order derivative - Kokkos::View ctrlPts_2ndDV("ctrlPts2Derivative", ctrlPts.extent(0)-2*(cPOffset.extent(0))); + Kokkos::View ctrlPts_2ndDV("ctrlPts2Derivative", ctrlPts.extent(0)-cPOffset.extent(0)); idx = 1; oidx = 0; diff --git a/testSplineKokkosBase.cpp b/testSplineKokkosBase.cpp index 40dda0d..294bf16 100644 --- a/testSplineKokkosBase.cpp +++ b/testSplineKokkosBase.cpp @@ -1,5 +1,6 @@ #include #include "BSplineKokkos.h" +#include "BSpline.h" #include #include @@ -94,6 +95,12 @@ int main(int argc, char* argv[]) { std::cout << "Spline created from list of splines" << std::endl; printSpline(fromList); + + //Testing for 1st Derivative + for (int i = 0; i < ex1.getCtrlPts().extent(0); i++) { + std::cout << ex1.evalFirstDeriv(ex1.getCtrlPts()(i), 0, 'x') << std::endl; + } + } Kokkos::finalize(); From 8e4b58c8814addd0e5d1fb557af231edf34957dc Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 17 Mar 2026 13:12:24 -0400 Subject: [PATCH 20/73] Fixing 1st deriv coe err 2nd deriv coe in progress --- BSplineKokkos.h | 44 ++++++++++++++++++++++++++++++++-------- testSplineKokkosBase.cpp | 4 ++-- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 7abec05..d92e6f0 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -168,6 +168,15 @@ class BSplineKokkos { cPOffset = cPOffsetV; knotsOffset = knotsOffsetV; calculateDerivCoeff(); + std::cout << "1st derivative" << std::endl; + for (int i = 0; i < ctrlPts_1stD.extent(0); i++){ + std::cout << ctrlPts_1stD(i) << std::endl; + } + std::cout << "2nd derivative" << std::endl; + for (int i = 0; i < ctrlPts_2ndD.extent(0); i++){ + std::cout << ctrlPts_2ndD.extent(0) << std::endl; + } + std::cout<<"constructor end" << std::endl; } @@ -279,7 +288,7 @@ class BSplineKokkos { //Moved here from the .cpp file since it uses //Calculate first order derivative //Allocate the space - Kokkos::View ctrlPts_1stDV("ctrlPts1Derivative", ctrlPts.extent(0)-(cPOffset.extent(0)/2)); + Kokkos::View ctrlPts_1stDV("ctrlPts1Derivative", ctrlPts.extent(0)-cPOffset.extent(0)); Kokkos::View cP1stDOffsetV("ctrlPts1DerivativeOffset", cPOffset.extent(0)); Kokkos::View cP2ndDOffsetV("ctrlPts2DerivativeOffset", cPOffset.extent(0)); cP2ndDOffsetV(0) = 0; @@ -295,23 +304,33 @@ class BSplineKokkos { int idx = 1; int oidx = 0; - std::cout << cPOffset(cPOffset.extent(0)-2) << std::endl; - for (int i = 1; i < cPOffset(cPOffset.extent(0)-2); i++) { + + for (int i = 1; i < ctrlPts.extent(0); i++) { if (i == cPOffset(idx)) { //Do not calculate, delta will be based on both x and y idx++; - if (idx % 2 == 0) { + if (idx % 2 != 0) { oidx++; + //This is a different spline with different order } continue; } + //std::cout << "Order: " << order(oidx) << std::endl; + //std::cout << "knots(i): " << knots(i) << std::endl; + //std::cout << "i+order(oidx)-1: " << knots(i+order(oidx)-1) << std::endl; double delta = double(order(oidx) - 1)/(knots(i+order(oidx)-1)-knots(i)); - std::cout << "delta: " << delta << std::endl; - ctrlPts_1stDV(i-1) = ((ctrlPts(i) - ctrlPts(i-1)*delta)); + + //std::cout << ctrlPts(i-1) << "|" << ctrlPts(i) << std::endl; + + + //std::cout << "delta: " << delta << std::endl; + //std::cout <<"current point: "<< ctrlPts(i) << std::endl; + ctrlPts_1stDV(i-1-(idx-1)) = ((ctrlPts(i) - ctrlPts(i-1)*delta)); + //std::cout <<"cP coefficient: "<< ctrlPts_1stDV(i-1) << std::endl; } //Calculate second order derivative - Kokkos::View ctrlPts_2ndDV("ctrlPts2Derivative", ctrlPts.extent(0)-cPOffset.extent(0)); + Kokkos::View ctrlPts_2ndDV("ctrlPts2Derivative", ctrlPts.extent(0)-2*cPOffset.extent(0)); idx = 1; oidx = 0; @@ -319,13 +338,20 @@ class BSplineKokkos { for (int i = 1; i < ctrlPts_1stDV.extent(0); i++) { if (i == cP1stDOffsetV(idx)) { idx++; - if (idx %2 == 0) { + if (idx %2 != 0) { oidx++; } continue; } + std::cout << "order: " << order(oidx) << std::endl; + std::cout << "i+order(oidx)-1" << std::endl; + std::cout << "knot at ^ position: " << knots(i+order(oidx)-1) << std::endl; + std::cout << "next knot: " << knots(i+1) << std::endl; double delta = double((order(oidx)-2))/(knots(i+order(oidx)-1)-knots(i+1)); - ctrlPts_2ndDV(i-1) = ctrlPts_1stDV(i) - ctrlPts_1stDV(i-1)*delta; + + std::cout << "delta: " << delta << std::endl; + ctrlPts_2ndDV(i-1-(idx-1)) = ctrlPts_1stDV(i) - ctrlPts_1stDV(i-1)*delta; + std::cout << "cP 2nd coefficient: " << ctrlPts_2ndDV(i-1) << std::endl; } ctrlPts_2ndD = ctrlPts_2ndDV; ctrlPts_1stD = ctrlPts_1stDV; diff --git a/testSplineKokkosBase.cpp b/testSplineKokkosBase.cpp index 294bf16..d35225d 100644 --- a/testSplineKokkosBase.cpp +++ b/testSplineKokkosBase.cpp @@ -81,8 +81,8 @@ int main(int argc, char* argv[]) { dummyCtrlPtsX.assign({18.29, 12.12, 5.92, 7.182, 1.16}); dummyCtrlPtsY.assign({4.72, 5.78, 9.12, 1.29, 10.2}); - dummyKnotsX.assign({4.34, 29.3, 18.7}); - dummyKnotsY.assign({19.12, 10.21, 12.78}); + dummyKnotsX.assign({4.34, 29.3, 18.7, 15.14, 16.87, 9.99}); + dummyKnotsY.assign({19.12, 10.21, 12.78, 8.12, 9.12, 12.12}); dOrder = 5; dummyWeights.assign({0.12, 0.182, 0.98, 0.05}); std::cout << "\t\tSTART OF MULTISPLINE CREATION" << std::endl; From d5707a8b890cab9dd19c5a9cbed44c745cc21922 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Wed, 18 Mar 2026 09:25:28 -0400 Subject: [PATCH 21/73] Fixing2nd deriv coe, 1&2 deriv coe need to verify --- BSplineKokkos.h | 43 +++++++++++-------------------------------- 1 file changed, 11 insertions(+), 32 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index d92e6f0..0430850 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -19,7 +19,6 @@ class BSplineKokkos { Kokkos::View orderV("Orders", 1); orderV(0) = order_p; order = orderV; - std::cout << "Order view added" << std::endl; //Initialize control points and their offset Kokkos::View ctrlPtsV("CtrlPoints", 2*ctrlPts_x.size()); for (int i = 0; i < ctrlPts_x.size(); i++) { @@ -65,14 +64,6 @@ class BSplineKokkos { //Derivative coefficients calculateDerivCoeff(); - std::cout << "1st derivative" << std::endl; - for (int i = 0; i < ctrlPts_1stD.extent(0); i++){ std::cout << ctrlPts_1stD(i) << std::endl; - } - std::cout << "2nd derivative" << std::endl; - for (int i = 0; i < ctrlPts_2ndD.extent(0); i++){ - std::cout << ctrlPts_2ndD.extent(0) << std::endl; - } - std::cout<<"constructor end" << std::endl; } @@ -168,23 +159,12 @@ class BSplineKokkos { cPOffset = cPOffsetV; knotsOffset = knotsOffsetV; calculateDerivCoeff(); - std::cout << "1st derivative" << std::endl; - for (int i = 0; i < ctrlPts_1stD.extent(0); i++){ - std::cout << ctrlPts_1stD(i) << std::endl; - } - std::cout << "2nd derivative" << std::endl; - for (int i = 0; i < ctrlPts_2ndD.extent(0); i++){ - std::cout << ctrlPts_2ndD.extent(0) << std::endl; - } - std::cout<<"constructor end" << std::endl; } double evalFirstDeriv(double x, int splineo, char coor) const { //Find the order based on the spline number given int lKnot = order(splineo)-1; - std::cout << "lKnot: " << lKnot << std::endl; - std::cout << "Order: " << order(splineo) < Date: Wed, 18 Mar 2026 10:19:23 -0400 Subject: [PATCH 22/73] 1st attempt at eval2ndDeriv --- BSplineKokkos.h | 59 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 0430850..0eabbd2 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -219,6 +219,61 @@ class BSplineKokkos { return pts(order_t-1); } + double evalSecondDeriv(double x, int splineo, char coor) const { + if (order == 2) { + return 0; + } + + int lKnot = order(splineo)-1; + int leftPt; + int bound; + if (coor == 'x') { + leftPt = (2*splineo); + bound = knotsOffset(2*splineo+1); + } else { + leftPt = knotsOffset(2*splineo+1); + bound = knotsOffset(2*(splineo+1)); + } + + while (knots(lKnot+1) < x && leftPt < bound) { + lKnot++; + leftPt++; + } + + //Populate pts and local knot views + int order_t = order(splineo)-2; + Kokkos::View pts("pts", order_t); + for (int i = leftPt; i < leftPt+order_t; i++) { + pts(i-leftPt) = ctrlPts_2ndD(i); + } + + Kokkos::View localKnots("localKnots", 2*order_t-2); + int idx = 0; + for (int i = lKnot-order_t+2; i < lKnot+order; i++) { + localKnots(idx) = knots(i); + idx++; + } + + Kokkos::parallel_for ("2nd derivative loop", order_t, KOKKOS_LAMBDA(int r){ + for (int i = order_t-1; i >= r+1; i--) { + double aLeft = localKnots(i-1); + double aRight = localKnots(i+order_t-(r+1)-1); + double alpha; + if (aLeft == aRight) { + alpha = 0; + } + else { + alpha = (x-aLeft)/(aRight-aLeft); + } + + pts(i) = (1. - alpha) * pts(i-1)+alpha*pts(i); + + } + }); + return pts(order_t-1); + + } + @@ -328,10 +383,6 @@ class BSplineKokkos { ctrlPts_2ndDV(i-1-(idx-1)) = ctrlPts_1stDV(i) - ctrlPts_1stDV(i-1)*delta; } - for (int i = 0; i < ctrlPts_2ndDV.extent(0); i++) { - std::cout << ctrlPts_2ndDV(i) << std::endl; - } - ctrlPts_2ndD = ctrlPts_2ndDV; ctrlPts_1stD = ctrlPts_1stDV; cP1stDOffset = cP1stDOffsetV; From dfafacb427f4573125ea4966b92c5f0551bc371f Mon Sep 17 00:00:00 2001 From: Hsieh Date: Mon, 23 Mar 2026 22:04:22 -0400 Subject: [PATCH 23/73] fixed indent & remove repeat knots, ongoing debug --- BSplineKokkos.h | 740 +++++++++++++++++++++++++----------------------- 1 file changed, 391 insertions(+), 349 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 0eabbd2..f7c6c8b 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -12,400 +12,442 @@ template class BSplineKokkos { public: - using MemSpace = typename ExecutionSpace::memory_space; - - //Constructor for just 1 spline(Would this be used often?) - BSplineKokkos(int order_p, std::vector& ctrlPts_x, std::vector& ctrlPts_y, std::vector& knots_x, std::vector& knots_y, std::vector& weights_p) { - Kokkos::View orderV("Orders", 1); - orderV(0) = order_p; - order = orderV; - //Initialize control points and their offset - Kokkos::View ctrlPtsV("CtrlPoints", 2*ctrlPts_x.size()); - for (int i = 0; i < ctrlPts_x.size(); i++) { - ctrlPtsV(i) = ctrlPts_x[i]; - } + using MemSpace = typename ExecutionSpace::memory_space; + + //Constructor for just 1 spline(Would this be used often?) + BSplineKokkos(int order_p, std::vector& ctrlPts_x, std::vector& ctrlPts_y, std::vector& knots_x, std::vector& knots_y, std::vector& weights_p) { + //In the original implementation, we had the x and y components separated and was storing redundant knots information + //The implementation now change to interleave the x and y coordinates + //We store just 1 set of knots rather than 2 + std::cout << "Start BSpline Construction" << std::endl; + Kokkos::View orderV("Orders", 1); + auto host_orderV = Kokkos::create_mirror_view(orderV); + host_orderV(0) = order_p; + Kokkos::deep_copy(orderV, host_orderV); + order = orderV; + std::cout << "Order inputted" << std::endl; + //Initialize control points and their offset + Kokkos::View ctrlPtsV("CtrlPoints", 2*ctrlPts_x.size()); + //Create the mirror on host so we can access the vector values + auto host_ctrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); + + for (int i = 0; i < ctrlPts_x.size(); i+=2) { + host_ctrlPtsV(i) = ctrlPts_x[i]; + host_ctrlPtsV(i+1) = ctrlPts_y[i]; + } - for (int i = 0; i < ctrlPts_y.size(); i++) { - ctrlPtsV(ctrlPts_x.size()+i) = ctrlPts_y[i]; - } + Kokkos::deep_copy(ctrlPtsV, host_ctrlPtsV); + ctrlPts = ctrlPtsV; - ctrlPts = ctrlPtsV; + Kokkos::View cPOffsetV("CtrlPointsOffset", 1); + auto host_cPOffsetV = Kokkos::create_mirror_view(cPOffsetV); + host_cPOffsetV(0) = 0; //Start of ctrlPts - Kokkos::View cPOffsetV("CtrlPointsOffset", 2); - cPOffsetV(0) = 0; //x coor start index - cPOffsetV(1) = ctrlPts_x.size(); //y coor start index + Kokkos::deep_copy(cPOffsetV, host_cPOffsetV); + cPOffset = cPOffsetV; - cPOffset = cPOffsetV; + //Initialize knots and their offset + Kokkos::View knotsV("Knots", knots_x.size()*2); - //Initialize knots and their offset - Kokkos::View knotsV("Knots", knots_x.size()*2); + Kokkos::View knotsOffsetV("KnotsOffset", 2); + auto host_knotsV = Kokkos::create_mirror_view(knotsV); + auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); + host_knotsOffsetV(0) = 0; + for (int i = 0; i < knots_x.size(); i+=2) { + host_knotsV(i) = knots_x[i]; + host_knotsV(i+1) = knots_y[i]; + } - Kokkos::View knotsOffsetV("KnotsOffset", 2); - knotsOffsetV(0) = 0; - knotsOffsetV(1) = knots_x.size(); + Kokkos::deep_copy(knotsV, host_knotsV); + Kokkos::deep_copy(knotsOffsetV, host_knotsOffsetV); + knots = knotsV; + knotsOffset = knotsOffsetV; - for (int i = 0; i < knots_x.size(); i++) { - knotsV(i) = knots_x[i]; - } - for (int i = 0; i < knots_y.size(); i++) { - knotsV(knotsOffsetV(1)+i) = knots_y[i]; - } + //Copy the weights over + Kokkos::View weightsV("Weights", weights_p.size()); + auto host_weightsV = Kokkos::create_mirror_view(weightsV); + for (int i = 0; i < weights_p.size(); i++) { + host_weightsV(i) = weights_p[i]; + } + Kokkos::deep_copy(weightsV, host_weightsV); + weights = weightsV; + + //Derivative coefficients + calculateDerivCoeff(); + } - knots = knotsV; - knotsOffset = knotsOffsetV; - //Copy the weights over - Kokkos::View weightsV("Weights", weights_p.size()); - for (int i = 0; i < weights_p.size(); i++) { - weightsV(i) = weights_p[i]; - } - weights = weightsV; - //Derivative coefficients - calculateDerivCoeff(); +//Create BSpline for a vector of BSplineKokkos objects + BSplineKokkos(std::vector& splines) { + //Preallocate space for Kokkos::View + //They are fixed in size and resize is expensive + int orderSize = 0; + int ctrlPSize = 0; + int knotsSize = 0; + int cPOffSize = 0; + int kOffSize = 0; + int weightSize = 0; + + //Input the offsets + //Track space needed to allocate for ctrlPts & knots + for (int i = 0; i < splines.size(); i++) { + cPOffSize += splines[i].getNumCtrlPts(); + kOffSize += splines[i].getNumKnots(); + ctrlPSize += splines[i].getCtrlPtsSize(); + knotsSize += splines[i].getKnotsSize(); + orderSize += splines[i].getOrder().extent(0); + weightSize += splines[i].getWeightSize(); + } + //Pre-Allocate space for views + Kokkos::View orderV ("Order", orderSize); + Kokkos::View ctrlPtsV ("CtrlPts", ctrlPSize); + Kokkos::View cPOffsetV ("CtrlPtsOffset", cPOffSize); + Kokkos::View knotsV("Knots", knotsSize); + Kokkos::View knotsOffsetV ("KnotsOffset", kOffSize); + Kokkos::View weightsV("Weights", weightSize); + auto host_orderV = Kokkos::create_mirror_view(orderV); + auto host_ctrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); + auto host_cPOffsetV = Kokkos::create_mirror_view(cPOffsetV); + auto host_knotsV = Kokkos::create_mirror_view(knotsV); + auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); + auto host_weightsV = Kokkos::create_mirror_view(weightsV); + + int oidx = 0; + int cPidx = 0; + int cOidx = 0; + int kidx = 0; + int kOidx = 0; + int widx = 0; + + //Populate the views with data + int cpLast = 0; + int kLast = 0; + + //NOTE TO SELF: INDEXING MAY BE WRONG + for (int i = 0; i < splines.size(); i++) { + + Kokkos::View intView = splines[i].getOrder(); + auto host_intView = Kokkos::create_mirror_view(intView); + //Populate order + for (int j = 0; j < intView.extent(0); j++) { + host_orderV(oidx+j)= host_intView(j); + } + oidx += host_intView.extent(0); + //Populate ctrlpts offset + //Offset the offset by the last offset in the view + intView = splines[i].getCPOffset(); + host_intView = Kokkos::create_mirror_view(intView); + for (int j = 0; j < host_intView.extent(0); j++) { + host_cPOffsetV(cOidx+j) = host_intView(j)+cpLast; + } + cOidx += host_intView.extent(0); + cpLast = host_cPOffsetV(cOidx-1)+(host_cPOffsetV(cOidx-1) - host_cPOffsetV(cOidx-2)); + //Populate knots offset + //Offset the offset by the last offset in the view + + intView = splines[i].getKnotsOffset(); + host_intView = Kokkos::create_mirror_view(intView); + for (int j = 0; j < host_intView.extent(0); j++) { + host_knotsOffsetV(kOidx+j) = host_intView(j)+kLast; + } + kOidx += host_intView.extent(0); + kLast = host_knotsOffsetV(kOidx-1)+(host_knotsOffsetV(kOidx-1) - host_knotsOffsetV(kOidx-2)); + + //Populate ctrlpts + Kokkos::View doubleView = splines[i].getCtrlPts(); + auto host_doubleView = Kokkos::create_mirror_view(doubleView); + for (int j = 0; j < host_doubleView.extent(0); j++) { + host_ctrlPtsV(cPidx+j) = host_doubleView(j); + } + cPidx += host_doubleView.extent(0); + //Populate knots + doubleView = splines[i].getKnots(); + host_doubleView = Kokkos::create_mirror_view(doubleView); + for (int j = 0; j < host_doubleView.extent(0); j++) { + host_knotsV(kidx+j) = host_doubleView(j); + } + kidx += host_doubleView.extent(0); + //Populate the weights + doubleView = splines[i].getWeights(); + host_doubleView = Kokkos::create_mirror_view(doubleView); + for (int j = 0; j < host_doubleView.extent(0); j++) { + host_weightsV(widx+j) = host_doubleView(j); + } + widx += host_doubleView.extent(0); + } + //Copy the modification made from the host data to the device view + Kokkos::deep_copy(orderV, host_orderV); + Kokkos::deep_copy(knotsV, host_knotsV); + Kokkos::deep_copy(ctrlPtsV, host_ctrlPtsV); + Kokkos::deep_copy(cPOffsetV, host_cPOffsetV); + Kokkos::deep_copy(weightsV, host_weightsV); + Kokkos::deep_copy(knotsOffsetV, host_knotsOffsetV); + + //Update the member variables + order = orderV; + knots = knotsV; + ctrlPts = ctrlPtsV; + weights = weightsV; + cPOffset = cPOffsetV; + knotsOffset = knotsOffsetV; + calculateDerivCoeff(); + + } + + double evalFirstDeriv(double x, int splineo, char coor) const { + //Find the order based on the spline number given + int lKnot = order(splineo)-1; + + //Find the range that contains this spline + //Need to make sure it is within the range of this spline + int leftPt; + int bound; + if (coor == 'x') { + //We are calculating the x component + leftPt = knotsOffset(2*splineo); + bound = knotsOffset(2*splineo+1); + } + else { + leftPt = knotsOffset(2*splineo+1); + bound = knotsOffset(2*(splineo+1)); + } + //Search within this range + while (knots(leftPt+1) < x && leftPt < bound) { + lKnot++; + leftPt++; } + int order_t = order(splineo)-1; + //Copy to view; + int idx = 0; + Kokkos::View pts("pts", order_t); + for (int i = leftPt; i < leftPt+order_t; i++) { + std::cout << i << "|" << ctrlPts_1stD(i) << std::endl; + pts(idx) = ctrlPts_1stD(i); + idx++; + } + idx = 0; + Kokkos::View localKnots("local knots", 2*order_t-2); + for (int i = lKnot-order_t+2; i < lKnot+order_t+1; i++) { + localKnots(idx) = knots(i); + } -//Create BSpline for a vector of BSplineKokkos objects - BSplineKokkos(std::vector& splines) { - //Preallocate space for Kokkos::View - //They are fixed in size and resize is expensive - int orderSize = 0; - int ctrlPSize = 0; - int knotsSize = 0; - int cPOffSize = 0; - int kOffSize = 0; - int weightSize = 0; - - //Input the offsets - //Track space needed to allocate for ctrlPts & knots - for (int i = 0; i < splines.size(); i++) { - cPOffSize += 2*(splines[i].getNumCtrlPts()); - kOffSize += 2*(splines[i].getNumKnots()); - ctrlPSize += splines[i].getCtrlPtsSize(); - knotsSize += splines[i].getKnotsSize(); - orderSize += splines[i].getOrder().extent(0); - weightSize += splines[i].getWeightSize(); - } - //Pre-Allocate space for views - Kokkos::View orderV ("Order", orderSize); - Kokkos::View ctrlPtsV ("CtrlPts", ctrlPSize); - Kokkos::View cPOffsetV ("CtrlPtsOffset", cPOffSize); - Kokkos::View knotsV("Knots", knotsSize); - Kokkos::View knotsOffsetV ("KnotsOffset", kOffSize); - Kokkos::View weightsV("Weights", weightSize); - - - int oidx = 0; - int cPidx = 0; - int cOidx = 0; - int kidx = 0; - int kOidx = 0; - int widx = 0; - //Populate the views with data - int cpLast = 0; - int kLast = 0; + Kokkos::parallel_for("1st derivative loop", order_t, KOKKOS_LAMBDA(int r) { + for (int i = order_t-1; i >= r+1; i--) { + double aLeft = localKnots(i-1); + double aRight = localKnots(i+order_t-(r+1)-1); + double alpha; + if (aLeft == aRight) { + alpha = 0.; + } + else { + alpha = (x-aLeft)/(aRight-aLeft); + } + pts(i) = (1. - alpha) * pts(i-1)+alpha*pts(i); + } + }); + return pts(order_t-1); + } + + double evalSecondDeriv(double x, int splineo, char coor) const { + if (order == 2) { + return 0; + } - for (int i = 0; i < splines.size(); i++) { - Kokkos::View intView = splines[i].getOrder(); - //Populate order - for (int j = 0; j < intView.extent(0); j++) { - orderV(oidx+j)= intView(j); - } - oidx += intView.extent(0); - //Populate ctrlpts offset - //Offset the offset by the last offset in the view - intView = splines[i].getCPOffset(); - for (int j = 0; j < intView.extent(0); j++) { - cPOffsetV(cOidx+j) = intView(j)+cpLast; - } - cOidx += intView.extent(0); - cpLast = cPOffsetV(cOidx-1)+(cPOffsetV(cOidx-1) - cPOffsetV(cOidx-2)); - //Populate knots offset - //Offset the offset by the last offset in the view - intView = splines[i].getKnotsOffset(); - for (int j = 0; j < intView.extent(0); j++) { - knotsOffsetV(kOidx+j) = intView(j)+kLast; - } - kOidx += intView.extent(0); - kLast = knotsOffsetV(kOidx-1)+(knotsOffsetV(kOidx-1) - knotsOffsetV(kOidx-2)); - - //Populate ctrlpts - Kokkos::View doubleView = splines[i].getCtrlPts(); - for (int j = 0; j < doubleView.extent(0); j++) { - ctrlPtsV(cPidx+j) = doubleView(j); - } - cPidx += doubleView.extent(0); - //Populate knots - doubleView = splines[i].getKnots(); - for (int j = 0; j < doubleView.extent(0); j++) { - knotsV(kidx+j) = doubleView(j); - } - kidx += doubleView.extent(0); - //Populate the weights - doubleView = splines[i].getWeights(); - for (int j = 0; j < doubleView.extent(0); j++) { - weightsV(widx+j) = doubleView(j); - } - widx += doubleView.extent(0); - } - order = orderV; - knots = knotsV; - ctrlPts = ctrlPtsV; - weights = weightsV; - cPOffset = cPOffsetV; - knotsOffset = knotsOffsetV; - calculateDerivCoeff(); + int lKnot = order(splineo)-1; + int leftPt; + int bound; + if (coor == 'x') { + leftPt = (2*splineo); + bound = knotsOffset(2*splineo+1); + } else { + leftPt = knotsOffset(2*splineo+1); + bound = knotsOffset(2*(splineo+1)); + } + while (knots(lKnot+1) < x && leftPt < bound) { + lKnot++; + leftPt++; } - double evalFirstDeriv(double x, int splineo, char coor) const { - //Find the order based on the spline number given - int lKnot = order(splineo)-1; - - //Find the range that contains this spline - //Need to make sure it is within the range of this spline - int leftPt; - int bound; - if (coor == 'x') { - //We are calculating the x component - leftPt = knotsOffset(2*splineo); - bound = knotsOffset(2*splineo+1); + //Populate pts and local knot views + int order_t = order(splineo)-2; + Kokkos::View pts("pts", order_t); + for (int i = leftPt; i < leftPt+order_t; i++) { + pts(i-leftPt) = ctrlPts_2ndD(i); + } + + Kokkos::View localKnots("localKnots", 2*order_t-2); + int idx = 0; + for (int i = lKnot-order_t+2; i < lKnot+order; i++) { + localKnots(idx) = knots(i); + idx++; + } + + Kokkos::parallel_for ("2nd derivative loop", order_t, KOKKOS_LAMBDA(int r){ + for (int i = order_t-1; i >= r+1; i--) { + double aLeft = localKnots(i-1); + double aRight = localKnots(i+order_t-(r+1)-1); + double alpha; + if (aLeft == aRight) { + alpha = 0; } else { - leftPt = knotsOffset(2*splineo+1); - bound = knotsOffset(2*(splineo+1)); - } - - //Search within this range - while (knots(leftPt+1) < x && leftPt < bound) { - lKnot++; - leftPt++; + alpha = (x-aLeft)/(aRight-aLeft); } - int order_t = order(splineo)-1; + pts(i) = (1. - alpha) * pts(i-1)+alpha*pts(i); + + } + }); + return pts(order_t-1); + + } - //Copy to view; - int idx = 0; - Kokkos::View pts("pts", order_t); - for (int i = leftPt; i < leftPt+order_t; i++) { - std::cout << i << "|" << ctrlPts_1stD(i) << std::endl; - pts(idx) = ctrlPts_1stD(i); - idx++; - } - idx = 0; - Kokkos::View localKnots("local knots", 2*order_t-2); - for (int i = lKnot-order_t+2; i < lKnot+order_t+1; i++) { - localKnots(idx) = knots(i); - } - Kokkos::parallel_for("1st derivative loop", order_t, KOKKOS_LAMBDA(int r) { - for (int i = order_t-1; i >= r+1; i--) { - double aLeft = localKnots(i-1); - double aRight = localKnots(i+order_t-(r+1)-1); - double alpha; - if (aLeft == aRight) { - alpha = 0.; - } - else { - alpha = (x-aLeft)/(aRight-aLeft); - } - pts(i) = (1. - alpha) * pts(i-1)+alpha*pts(i); - } - }); - return pts(order_t-1); - } - double evalSecondDeriv(double x, int splineo, char coor) const { - if (order == 2) { - return 0; - } - - int lKnot = order(splineo)-1; - int leftPt; - int bound; - if (coor == 'x') { - leftPt = (2*splineo); - bound = knotsOffset(2*splineo+1); - } else { - leftPt = knotsOffset(2*splineo+1); - bound = knotsOffset(2*(splineo+1)); - } - while (knots(lKnot+1) < x && leftPt < bound) { - lKnot++; - leftPt++; - } - //Populate pts and local knot views - int order_t = order(splineo)-2; - Kokkos::View pts("pts", order_t); - for (int i = leftPt; i < leftPt+order_t; i++) { - pts(i-leftPt) = ctrlPts_2ndD(i); - } - - Kokkos::View localKnots("localKnots", 2*order_t-2); - int idx = 0; - for (int i = lKnot-order_t+2; i < lKnot+order; i++) { - localKnots(idx) = knots(i); - idx++; - } + //Accessors + Kokkos::View getOrder() const {return order;} + Kokkos::View getCtrlPts() const {return ctrlPts;} + Kokkos::View getKnots() const {return knots;} + Kokkos::View getWeights() const {return weights;} + Kokkos::View getCPOffset() const {return cPOffset;} + Kokkos::View getKnotsOffset() const {return knotsOffset;} + Kokkos::View get1stD() const {return ctrlPts_1stD;} + Kokkos::View get2ndD() const {return ctrlPts_2ndD;} + + + int getNumCtrlPts() const {return cPOffset.extent(0)/2;} + int getNumKnots() const {return knotsOffset.extent(0)/2;} + int getCtrlPtsSize() const {return ctrlPts.extent(0);} + int getKnotsSize() const {return knots.extent(0);} + int getWeightSize() const {return weights.extent(0);} + int getOrderSize() const {return order.extent(0);} + + double getCtrlPtCoor(int BspIdx, int cPIdx, char coor) const { + if (coor == 'x') { + //Find the correct offset + return ctrlPts(cPOffset(2*BspIdx)+cPIdx); + } + else { + return ctrlPts(cPOffset(2*BspIdx+1)+cPIdx); + } + } + double getKnotCoor(int BspIdx, int kIdx, char coor) const { + if (coor == 'x') { + return knots(knotsOffset(2*BspIdx)+kIdx); + } + else { + return knots(knotsOffset(2*BspIdx+1)+kIdx); + } + } - Kokkos::parallel_for ("2nd derivative loop", order_t, KOKKOS_LAMBDA(int r){ - for (int i = order_t-1; i >= r+1; i--) { - double aLeft = localKnots(i-1); - double aRight = localKnots(i+order_t-(r+1)-1); - double alpha; - if (aLeft == aRight) { - alpha = 0; - } - else { - alpha = (x-aLeft)/(aRight-aLeft); - } - - pts(i) = (1. - alpha) * pts(i-1)+alpha*pts(i); - - } - }); - return pts(order_t-1); + void calculateDerivCoeff() { + //Moved here from the .cpp file since it uses + //Calculate first order derivative + //Allocate the space + + std::cout << "calculating derivative coeff" << std::endl; + Kokkos::View ctrlPts_1stDV("ctrlPts1Derivative", ctrlPts.extent(0)-cPOffset.extent(0)); + Kokkos::View cP1stDOffsetV("ctrlPts1DerivativeOffset", cPOffset.extent(0)); + Kokkos::View cP2ndDOffsetV("ctrlPts2DerivativeOffset", cPOffset.extent(0)); + + auto host_cP2ndDOffsetV = Kokkos::create_mirror_view(cP2ndDOffsetV); + + auto host_cP1stDOffsetV = Kokkos::create_mirror_view(cP1stDOffsetV); + host_cP2ndDOffsetV(0) = 0; + std::cout << "offset views and 1stctrlPts views construct" << std::endl; + + //Adjust the offset to include be 1 & 2 less than the ctrlPtsOffset + host_cP1stDOffsetV(0) = 0; + for (int i = 1; i < cPOffset.extent(0); i++) { + host_cP1stDOffsetV(i) = cPOffset(i)-1; + host_cP2ndDOffsetV(i) = cPOffset(i)-2; } + //We need to partition the x and y while we calculate the coefficient + int idx = 1; + int oidx = 0; + for (int i = 1; i < ctrlPts.extent(0); i++) { + if (i == cPOffset(idx)) { + //Do not calculate, delta will be based on both x and y + idx++; + if (idx % 2 != 0) { + oidx++; + //This is a different spline with different order + } + continue; + } + //std::cout << "Order: " << order(oidx) << std::endl; + //std::cout << "knots(i): " << knots(i) << std::endl; + //std::cout << "i+order(oidx)-1: " << knots(i+order(oidx)-1) << std::endl; + double delta = double(order(oidx) - 1)/(knots(i+order(oidx)-1)-knots(i)); + //std::cout << ctrlPts(i-1) << "|" << ctrlPts(i) << std::endl; - //Accessors - Kokkos::View getOrder() const {return order;} - Kokkos::View getCtrlPts() const {return ctrlPts;} - Kokkos::View getKnots() const {return knots;} - Kokkos::View getWeights() const {return weights;} - Kokkos::View getCPOffset() const {return cPOffset;} - Kokkos::View getKnotsOffset() const {return knotsOffset;} - Kokkos::View get1stD() const {return ctrlPts_1stD;} - Kokkos::View get2ndD() const {return ctrlPts_2ndD;} - - - int getNumCtrlPts() const {return cPOffset.extent(0)/2;} - int getNumKnots() const {return knotsOffset.extent(0)/2;} - int getCtrlPtsSize() const {return ctrlPts.extent(0);} - int getKnotsSize() const {return knots.extent(0);} - int getWeightSize() const {return weights.extent(0);} - int getOrderSize() const {return order.extent(0);} - - double getCtrlPtCoor(int BspIdx, int cPIdx, char coor) const { - if (coor == 'x') { - //Find the correct offset - return ctrlPts(cPOffset(2*BspIdx)+cPIdx); - } - else { - return ctrlPts(cPOffset(2*BspIdx+1)+cPIdx); - } - } - double getKnotCoor(int BspIdx, int kIdx, char coor) const { - if (coor == 'x') { - return knots(knotsOffset(2*BspIdx)+kIdx); - } - else { - return knots(knotsOffset(2*BspIdx+1)+kIdx); - } + + //std::cout << "delta: " << delta << std::endl; + //std::cout <<"current point: "<< ctrlPts(i) << std::endl; + ctrlPts_1stDV(i-1-(idx-1)) = ((ctrlPts(i) - ctrlPts(i-1)*delta)); + //std::cout <<"cP coefficient: "<< ctrlPts_1stDV(i-1) << std::endl; } - void calculateDerivCoeff() { - //Moved here from the .cpp file since it uses - //Calculate first order derivative - //Allocate the space - Kokkos::View ctrlPts_1stDV("ctrlPts1Derivative", ctrlPts.extent(0)-cPOffset.extent(0)); - Kokkos::View cP1stDOffsetV("ctrlPts1DerivativeOffset", cPOffset.extent(0)); - Kokkos::View cP2ndDOffsetV("ctrlPts2DerivativeOffset", cPOffset.extent(0)); - cP2ndDOffsetV(0) = 0; - - //Adjust the offset to include be 1 & 2 less than the ctrlPtsOffset - cP1stDOffsetV(0) = 0; - for (int i = 1; i < cPOffset.extent(0); i++) { - cP1stDOffsetV(i) = cPOffset(i)-1; - cP2ndDOffsetV(i) = cPOffset(i)-2; - } + //Calculate second order derivative + Kokkos::View ctrlPts_2ndDV("ctrlPts2Derivative", ctrlPts.extent(0)-2*cPOffset.extent(0)); - //We need to partition the x and y while we calculate the coefficient - int idx = 1; - int oidx = 0; - - - for (int i = 1; i < ctrlPts.extent(0); i++) { - if (i == cPOffset(idx)) { - //Do not calculate, delta will be based on both x and y - idx++; - if (idx % 2 != 0) { - oidx++; - //This is a different spline with different order - } - continue; - } - //std::cout << "Order: " << order(oidx) << std::endl; - //std::cout << "knots(i): " << knots(i) << std::endl; - //std::cout << "i+order(oidx)-1: " << knots(i+order(oidx)-1) << std::endl; - double delta = double(order(oidx) - 1)/(knots(i+order(oidx)-1)-knots(i)); - - //std::cout << ctrlPts(i-1) << "|" << ctrlPts(i) << std::endl; - - - //std::cout << "delta: " << delta << std::endl; - //std::cout <<"current point: "<< ctrlPts(i) << std::endl; - ctrlPts_1stDV(i-1-(idx-1)) = ((ctrlPts(i) - ctrlPts(i-1)*delta)); - //std::cout <<"cP coefficient: "<< ctrlPts_1stDV(i-1) << std::endl; - } + idx = 1; + oidx = 0; - //Calculate second order derivative - Kokkos::View ctrlPts_2ndDV("ctrlPts2Derivative", ctrlPts.extent(0)-2*cPOffset.extent(0)); - - idx = 1; - oidx = 0; - - for (int i = 1; i < ctrlPts_1stDV.extent(0); i++) { - if (i == cP1stDOffsetV(idx)) { - idx++; - if (idx %2 != 0) { - oidx++; - } - continue; - } - if (order(oidx) == 2) { - //This will cause problem, it should be 0 anyway - ctrlPts_2ndDV(i-1-(idx-1)) = 0; - continue; - - } - double delta = double((order(oidx)-2))/(knots(i+order(oidx)-1)-knots(i+1)); - ctrlPts_2ndDV(i-1-(idx-1)) = ctrlPts_1stDV(i) - ctrlPts_1stDV(i-1)*delta; + for (int i = 1; i < ctrlPts_1stDV.extent(0); i++) { + if (i == host_cP1stDOffsetV(idx)) { + idx++; + if (idx %2 != 0) { + oidx++; } - - ctrlPts_2ndD = ctrlPts_2ndDV; - ctrlPts_1stD = ctrlPts_1stDV; - cP1stDOffset = cP1stDOffsetV; - cP2ndDOffset = cP2ndDOffsetV; + continue; + } + if (order(oidx) == 2) { + //This will cause problem, it should be 0 anyway + ctrlPts_2ndDV(i-1-(idx-1)) = 0; + continue; + + } + double delta = double((order(oidx)-2))/(knots(i+order(oidx)-1)-knots(i+1)); + ctrlPts_2ndDV(i-1-(idx-1)) = ctrlPts_1stDV(i) - ctrlPts_1stDV(i-1)*delta; } + + ctrlPts_2ndD = ctrlPts_2ndDV; + ctrlPts_1stD = ctrlPts_1stDV; + cP1stDOffset = cP1stDOffsetV; + cP2ndDOffset = cP2ndDOffsetV; + } - private: + private: - Kokkos::View order; - - //CtrlPts, knots, weights and their offsets - Kokkos::View ctrlPts; - Kokkos::View cPOffset; - Kokkos::View knots; - Kokkos::View knotsOffset; - Kokkos::View weights; - //weight offset may be added later, not entirely sure for now - - //The 1st and 2nd derivatives - Kokkos::View ctrlPts_1stD; - Kokkos::View cP1stDOffset; - Kokkos::View ctrlPts_2ndD; - Kokkos::View cP2ndDOffset; + Kokkos::View order; + + //CtrlPts, knots, weights and their offsets + Kokkos::View ctrlPts; + Kokkos::View cPOffset; + Kokkos::View knots; + Kokkos::View knotsOffset; + Kokkos::View weights; + //weight offset may be added later, not entirely sure for now + + //The 1st and 2nd derivatives + Kokkos::View ctrlPts_1stD; + Kokkos::View cP1stDOffset; + Kokkos::View ctrlPts_2ndD; + Kokkos::View cP2ndDOffset; }; #endif From f788662a1e82084137b359ff495ed7854933614d Mon Sep 17 00:00:00 2001 From: Hsieh Date: Mon, 23 Mar 2026 22:08:28 -0400 Subject: [PATCH 24/73] fixing indentation to match existing code --- testSplineKokkosBase.cpp | 149 +++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 75 deletions(-) diff --git a/testSplineKokkosBase.cpp b/testSplineKokkosBase.cpp index d35225d..7bc261a 100644 --- a/testSplineKokkosBase.cpp +++ b/testSplineKokkosBase.cpp @@ -6,102 +6,101 @@ template void printDView(Kokkos::View& dView) { - for (int i = 0; i < dView.extent(0); i++) { - std::cout << dView(i) << std::endl; - } + for (int i = 0; i < dView.extent(0); i++) { + std::cout << dView(i) << std::endl; + } } template void printIView(Kokkos::View& iView) { - for (int i = 0; i < iView.extent(0); i++) { - std::cout << iView(i) << std::endl; - } + for (int i = 0; i < iView.extent(0); i++) { + std::cout << iView(i) << std::endl; + } } template void printSpline(BSplineKokkos spline) { - std::cout << "Spline content" << std::endl; - Kokkos::View dView = spline.getCtrlPts(); - std::cout << "CtrlPts" << std::endl; - printDView(dView); - Kokkos::View iView = spline.getCPOffset(); - std::cout << "CtrlPts Offset" << std::endl; - printIView(iView); - dView = spline.getKnots(); - std::cout << "Knots" << std::endl; - printDView(dView); - iView = spline.getKnotsOffset(); - std::cout << "Knots Offset" << std::endl; - printIView(iView); + std::cout << "Spline content" << std::endl; + Kokkos::View dView = spline.getCtrlPts(); + std::cout << "CtrlPts" << std::endl; + printDView(dView); + Kokkos::View iView = spline.getCPOffset(); + std::cout << "CtrlPts Offset" << std::endl; + printIView(iView); + dView = spline.getKnots(); + std::cout << "Knots" << std::endl; + printDView(dView); + iView = spline.getKnotsOffset(); + std::cout << "Knots Offset" << std::endl; + printIView(iView); } int main(int argc, char* argv[]) { - Kokkos::initialize(argc, argv); - { - //Check for what memory space we should use + Kokkos::initialize(argc, argv); + { + //Check for what memory space we should use //Sticking to just cuda space or host space for now - #ifdef KOKKOS_ENABLE_CUDA - #define MemSpace Kokkos::CudaSpace - #endif - #ifndef MemSpace - #define MemSpace Kokkos::HostSpace - #endif - - using ExecutionSpace = MemSpace::execution_space; + #ifdef KOKKOS_ENABLE_CUDA + #define MemSpace Kokkos::CudaSpace + #endif + #ifndef MemSpace + #define MemSpace Kokkos::HostSpace + #endif - //We will try to test with dummy data for BSplineKokkos creation - std::vector dummyCtrlPtsX{2.14, 3.98, 1.56, 9.10, 11.87}; + using ExecutionSpace = MemSpace::execution_space; + //We will try to test with dummy data for BSplineKokkos creation + std::vector dummyCtrlPtsX{2.14, 3.98, 1.56, 9.10, 11.87}; - std::vector dummyCtrlPtsY{7.928, 12.18, 9.17, 6.67, 12.78}; - std::vector dummyKnotsX{5.99, 8.98, 17.71, 21.1, 2.154, 9.17, 6.32}; - std::vector dummyKnotsY{2.85, 1.16, 0.82, 1.89, 9.82, 12.0, 7.19}; - int dOrder = 2; - std::vector dummyWeights{0.87, 0.125, 0.03}; - //Initialize 1 Kokkos Spline - BSplineKokkos ex1(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); + std::vector dummyCtrlPtsY{7.928, 12.18, 9.17, 6.67, 12.78}; + std::vector dummyKnotsX{5.99, 8.98, 17.71, 21.1, 2.154, 9.17, 6.32}; + std::vector dummyKnotsY{2.85, 1.16, 0.82, 1.89, 9.82, 12.0, 7.19}; + int dOrder = 2; + std::vector dummyWeights{0.87, 0.125, 0.03}; + //Initialize 1 Kokkos Spline + BSplineKokkos ex1(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); - //Check if we actually initialized with correct values - std::cout << "ex1" << std::endl; - printSpline(ex1); - std::vector> splineList; - splineList.push_back(ex1); + //Check if we actually initialized with correct values + std::cout << "ex1" << std::endl; + printSpline(ex1); + std::vector> splineList; + splineList.push_back(ex1); - //Test constructor that takes in multiple BSplineKokkos objects - dummyCtrlPtsX.assign({1.20, 12.91, 7.11}); - dummyCtrlPtsY.assign({3.31, 7.89, 9.12}); - dummyKnotsX.assign({2.18, 5.56, 3.18, 16.15}); - dummyKnotsY.assign({1.971,4.12, 8.192, 12.11}); - dOrder = 3; - dummyWeights.assign({0.19, 0.27}); - BSplineKokkos ex2(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); - splineList.push_back(ex2); - std::cout << "ex2" << std::endl; - printSpline(ex2); + //Test constructor that takes in multiple BSplineKokkos objects + dummyCtrlPtsX.assign({1.20, 12.91, 7.11}); + dummyCtrlPtsY.assign({3.31, 7.89, 9.12}); + dummyKnotsX.assign({2.18, 5.56, 3.18, 16.15}); + dummyKnotsY.assign({1.971,4.12, 8.192, 12.11}); + dOrder = 3; + dummyWeights.assign({0.19, 0.27}); + BSplineKokkos ex2(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); + splineList.push_back(ex2); + std::cout << "ex2" << std::endl; + printSpline(ex2); - dummyCtrlPtsX.assign({18.29, 12.12, 5.92, 7.182, 1.16}); - dummyCtrlPtsY.assign({4.72, 5.78, 9.12, 1.29, 10.2}); - dummyKnotsX.assign({4.34, 29.3, 18.7, 15.14, 16.87, 9.99}); - dummyKnotsY.assign({19.12, 10.21, 12.78, 8.12, 9.12, 12.12}); - dOrder = 5; - dummyWeights.assign({0.12, 0.182, 0.98, 0.05}); - std::cout << "\t\tSTART OF MULTISPLINE CREATION" << std::endl; - BSplineKokkos ex3(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); - splineList.push_back(ex3); - std::cout << "ex3" << std::endl; - printSpline(ex3); + dummyCtrlPtsX.assign({18.29, 12.12, 5.92, 7.182, 1.16}); + dummyCtrlPtsY.assign({4.72, 5.78, 9.12, 1.29, 10.2}); + dummyKnotsX.assign({4.34, 29.3, 18.7, 15.14, 16.87, 9.99}); + dummyKnotsY.assign({19.12, 10.21, 12.78, 8.12, 9.12, 12.12}); + dOrder = 5; + dummyWeights.assign({0.12, 0.182, 0.98, 0.05}); + std::cout << "\t\tSTART OF MULTISPLINE CREATION" << std::endl; + BSplineKokkos ex3(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); + splineList.push_back(ex3); + std::cout << "ex3" << std::endl; + printSpline(ex3); - BSplineKokkos fromList(splineList); + BSplineKokkos fromList(splineList); - std::cout << "Spline created from list of splines" << std::endl; - printSpline(fromList); + std::cout << "Spline created from list of splines" << std::endl; + printSpline(fromList); - //Testing for 1st Derivative - for (int i = 0; i < ex1.getCtrlPts().extent(0); i++) { - std::cout << ex1.evalFirstDeriv(ex1.getCtrlPts()(i), 0, 'x') << std::endl; - } + //Testing for 1st Derivative + for (int i = 0; i < ex1.getCtrlPts().extent(0); i++) { + std::cout << ex1.evalFirstDeriv(ex1.getCtrlPts()(i), 0, 'x') << std::endl; + } - } - Kokkos::finalize(); + } + Kokkos::finalize(); } From bc562b991dde7e553ee666ec206983be9985ff30 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 24 Mar 2026 21:33:12 -0400 Subject: [PATCH 25/73] fixing memory access error for spline constructors --- BSplineKokkos.h | 130 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 91 insertions(+), 39 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index f7c6c8b..de96a1c 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -23,46 +23,48 @@ class BSplineKokkos { Kokkos::View orderV("Orders", 1); auto host_orderV = Kokkos::create_mirror_view(orderV); host_orderV(0) = order_p; - Kokkos::deep_copy(orderV, host_orderV); - order = orderV; + order = orderV; + Kokkos::deep_copy(order, host_orderV); std::cout << "Order inputted" << std::endl; //Initialize control points and their offset Kokkos::View ctrlPtsV("CtrlPoints", 2*ctrlPts_x.size()); //Create the mirror on host so we can access the vector values auto host_ctrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); + std::cout << "ctrlPts size: " << host_ctrlPtsV.extent(0) << std::endl; - for (int i = 0; i < ctrlPts_x.size(); i+=2) { - host_ctrlPtsV(i) = ctrlPts_x[i]; - host_ctrlPtsV(i+1) = ctrlPts_y[i]; + for (int i = 0; i < ctrlPts_x.size(); i++) { + host_ctrlPtsV(2*i) = ctrlPts_x[i]; + host_ctrlPtsV((2*i)+1) = ctrlPts_y[i]; } - Kokkos::deep_copy(ctrlPtsV, host_ctrlPtsV); ctrlPts = ctrlPtsV; + Kokkos::deep_copy(ctrlPts, host_ctrlPtsV); Kokkos::View cPOffsetV("CtrlPointsOffset", 1); auto host_cPOffsetV = Kokkos::create_mirror_view(cPOffsetV); host_cPOffsetV(0) = 0; //Start of ctrlPts - Kokkos::deep_copy(cPOffsetV, host_cPOffsetV); cPOffset = cPOffsetV; + Kokkos::deep_copy(cPOffset, host_cPOffsetV); //Initialize knots and their offset Kokkos::View knotsV("Knots", knots_x.size()*2); - Kokkos::View knotsOffsetV("KnotsOffset", 2); + Kokkos::View knotsOffsetV("KnotsOffset", 1); auto host_knotsV = Kokkos::create_mirror_view(knotsV); auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); host_knotsOffsetV(0) = 0; - for (int i = 0; i < knots_x.size(); i+=2) { - host_knotsV(i) = knots_x[i]; - host_knotsV(i+1) = knots_y[i]; + for (int i = 0; i < knots_x.size(); i++) { + host_knotsV(2*i) = knots_x[i]; + host_knotsV((2*i)+1) = knots_y[i]; } - Kokkos::deep_copy(knotsV, host_knotsV); - Kokkos::deep_copy(knotsOffsetV, host_knotsOffsetV); knots = knotsV; + Kokkos::deep_copy(knots, host_knotsV); + knotsOffset = knotsOffsetV; + Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); //Copy the weights over Kokkos::View weightsV("Weights", weights_p.size()); @@ -70,12 +72,14 @@ class BSplineKokkos { for (int i = 0; i < weights_p.size(); i++) { host_weightsV(i) = weights_p[i]; } - Kokkos::deep_copy(weightsV, host_weightsV); weights = weightsV; - + Kokkos::deep_copy(weights, host_weightsV); + + std::cout << "All good, before derivative coe" << std::endl; //Derivative coefficients - calculateDerivCoeff(); - } + calculateDerivCoeff(); + std::cout << "single spline initialization ok" << std::endl; + } @@ -127,20 +131,27 @@ class BSplineKokkos { //NOTE TO SELF: INDEXING MAY BE WRONG for (int i = 0; i < splines.size(); i++) { - Kokkos::View intView = splines[i].getOrder(); auto host_intView = Kokkos::create_mirror_view(intView); + Kokkos::deep_copy(host_intView, intView); //Populate order for (int j = 0; j < intView.extent(0); j++) { host_orderV(oidx+j)= host_intView(j); + std::cout << "Spline Order: " << host_orderV(oidx+j) << std::endl; } oidx += host_intView.extent(0); //Populate ctrlpts offset //Offset the offset by the last offset in the view intView = splines[i].getCPOffset(); host_intView = Kokkos::create_mirror_view(intView); + Kokkos::deep_copy(host_intView, intView); + host_intView = Kokkos::create_mirror_view(intView); for (int j = 0; j < host_intView.extent(0); j++) { - host_cPOffsetV(cOidx+j) = host_intView(j)+cpLast; + std::cout << "\tctrlPtsOffset: " << host_intView(j) << std::endl; + std::cout << "\tcpLast: " << cpLast << std::endl; + std::cout << "cOidx: " << cOidx << std::endl; + host_cPOffsetV(cOidx+j) = host_intView(j)+cpLast; + } cOidx += host_intView.extent(0); cpLast = host_cPOffsetV(cOidx-1)+(host_cPOffsetV(cOidx-1) - host_cPOffsetV(cOidx-2)); @@ -149,6 +160,7 @@ class BSplineKokkos { intView = splines[i].getKnotsOffset(); host_intView = Kokkos::create_mirror_view(intView); + Kokkos::deep_copy(host_intView, intView); for (int j = 0; j < host_intView.extent(0); j++) { host_knotsOffsetV(kOidx+j) = host_intView(j)+kLast; } @@ -158,6 +170,7 @@ class BSplineKokkos { //Populate ctrlpts Kokkos::View doubleView = splines[i].getCtrlPts(); auto host_doubleView = Kokkos::create_mirror_view(doubleView); + Kokkos::deep_copy(host_doubleView, doubleView); for (int j = 0; j < host_doubleView.extent(0); j++) { host_ctrlPtsV(cPidx+j) = host_doubleView(j); } @@ -165,6 +178,7 @@ class BSplineKokkos { //Populate knots doubleView = splines[i].getKnots(); host_doubleView = Kokkos::create_mirror_view(doubleView); + Kokkos::deep_copy(host_doubleView, doubleView); for (int j = 0; j < host_doubleView.extent(0); j++) { host_knotsV(kidx+j) = host_doubleView(j); } @@ -172,18 +186,12 @@ class BSplineKokkos { //Populate the weights doubleView = splines[i].getWeights(); host_doubleView = Kokkos::create_mirror_view(doubleView); + Kokkos::deep_copy(host_doubleView, doubleView); for (int j = 0; j < host_doubleView.extent(0); j++) { host_weightsV(widx+j) = host_doubleView(j); } widx += host_doubleView.extent(0); } - //Copy the modification made from the host data to the device view - Kokkos::deep_copy(orderV, host_orderV); - Kokkos::deep_copy(knotsV, host_knotsV); - Kokkos::deep_copy(ctrlPtsV, host_ctrlPtsV); - Kokkos::deep_copy(cPOffsetV, host_cPOffsetV); - Kokkos::deep_copy(weightsV, host_weightsV); - Kokkos::deep_copy(knotsOffsetV, host_knotsOffsetV); //Update the member variables order = orderV; @@ -192,7 +200,16 @@ class BSplineKokkos { weights = weightsV; cPOffset = cPOffsetV; knotsOffset = knotsOffsetV; - calculateDerivCoeff(); + //Copy the modification made from the host data to the device view + Kokkos::deep_copy(order, host_orderV); + Kokkos::deep_copy(knots, host_knotsV); + Kokkos::deep_copy(ctrlPts, host_ctrlPtsV); + Kokkos::deep_copy(cPOffset, host_cPOffsetV); + Kokkos::deep_copy(weights, host_weightsV); + Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); + + //TO DO: Work on calculate derivative coeff + //calculateDerivCoeff(); } @@ -367,18 +384,45 @@ class BSplineKokkos { //Adjust the offset to include be 1 & 2 less than the ctrlPtsOffset host_cP1stDOffsetV(0) = 0; - for (int i = 1; i < cPOffset.extent(0); i++) { - host_cP1stDOffsetV(i) = cPOffset(i)-1; - host_cP2ndDOffsetV(i) = cPOffset(i)-2; + + auto host_cPOffset = Kokkos::create_mirror_view(cPOffset); + if (host_cPOffset.extent(0) > 1) { + Kokkos::deep_copy(host_cPOffset, cPOffset); + for (int i = 1; i < cPOffset.extent(0); i++) { + host_cP1stDOffsetV(i) = host_cPOffset(i)-1; + host_cP2ndDOffsetV(i) = host_cPOffset(i)-2; + std::cout << "1st: " << host_cP1stDOffsetV(i); + std::cout << ", 2nd: " << host_cP2ndDOffsetV(i) << std::endl; + } } + std::cout << "offset view populated" << std::endl; + //We need to partition the x and y while we calculate the coefficient - int idx = 1; + /*int idx = 1; int oidx = 0; + auto host_knots = Kokkos::create_mirror_view(knots); + auto host_order = Kokkos::create_mirror_view(order); + auto host_ctrlPts = Kokkos::create_mirror_view(ctrlPts); + auto host_ctrlPts_1stDV = Kokkos::create_mirror_view(ctrlPts_1stDV); + + //Copy these value over + Kokkos::deep_copy(host_knots, knots); + Kokkos::deep_copy(host_order, order); + Kokkos::deep_copy(host_ctrlPts, ctrlPts); + //We need to keep track of the indicies of the splines for (int i = 1; i < ctrlPts.extent(0); i++) { - if (i == cPOffset(idx)) { + //Even indices stores all the x coordinates + //Odd indices stores all the y coordinates + + }*/ + + //Now that we interleave the data, we need to calculate the coordinates carefully + /* + for (int i = 1; i < ctrlPts.extent(0); i++) { + if (i == host_cPOffset(idx)) { //Do not calculate, delta will be based on both x and y idx++; if (idx % 2 != 0) { @@ -390,20 +434,23 @@ class BSplineKokkos { //std::cout << "Order: " << order(oidx) << std::endl; //std::cout << "knots(i): " << knots(i) << std::endl; //std::cout << "i+order(oidx)-1: " << knots(i+order(oidx)-1) << std::endl; - double delta = double(order(oidx) - 1)/(knots(i+order(oidx)-1)-knots(i)); + double delta = double(host_order(oidx) - 1)/(host_knots(i+host_order(oidx)-1)-host_knots(i)); //std::cout << ctrlPts(i-1) << "|" << ctrlPts(i) << std::endl; //std::cout << "delta: " << delta << std::endl; //std::cout <<"current point: "<< ctrlPts(i) << std::endl; - ctrlPts_1stDV(i-1-(idx-1)) = ((ctrlPts(i) - ctrlPts(i-1)*delta)); + host_ctrlPts_1stDV(i-1-(idx-1)) = ((host_ctrlPts(i) - host_ctrlPts(i-1)*delta)); //std::cout <<"cP coefficient: "<< ctrlPts_1stDV(i-1) << std::endl; } + std::cout << "end of 1stD coe calculation" << std::endl; //Calculate second order derivative Kokkos::View ctrlPts_2ndDV("ctrlPts2Derivative", ctrlPts.extent(0)-2*cPOffset.extent(0)); + auto host_ctrlPts_2ndDV = Kokkos::create_mirror_view(ctrlPts_2ndDV); + idx = 1; oidx = 0; @@ -415,20 +462,25 @@ class BSplineKokkos { } continue; } - if (order(oidx) == 2) { + if (host_order(oidx) == 2) { //This will cause problem, it should be 0 anyway - ctrlPts_2ndDV(i-1-(idx-1)) = 0; + host_ctrlPts_2ndDV(i-1-(idx-1)) = 0; continue; } - double delta = double((order(oidx)-2))/(knots(i+order(oidx)-1)-knots(i+1)); - ctrlPts_2ndDV(i-1-(idx-1)) = ctrlPts_1stDV(i) - ctrlPts_1stDV(i-1)*delta; + double delta = double((host_order(oidx)-2))/(host_knots(i+host_order(oidx)-1)-host_knots(i+1)); + host_ctrlPts_2ndDV(i-1-(idx-1)) = host_ctrlPts_1stDV(i) - host_ctrlPts_1stDV(i-1)*delta; } + Kokkos::deep_copy(cP1stDOffsetV, host_cP1stDOffsetV); + Kokkos::deep_copy(cP2ndDOffsetV, host_cP2ndDOffsetV); + Kokkos::deep_copy(ctrlPts_1stDV, host_ctrlPts_1stDV); + Kokkos::deep_copy(ctrlPts_2ndDV, host_ctrlPts_2ndDV); + ctrlPts_2ndD = ctrlPts_2ndDV; ctrlPts_1stD = ctrlPts_1stDV; cP1stDOffset = cP1stDOffsetV; - cP2ndDOffset = cP2ndDOffsetV; + cP2ndDOffset = cP2ndDOffsetV;*/ } private: From 2b8d27cfd196d7ef5ee3a98adeb87ce3ddca974e Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 24 Mar 2026 21:34:24 -0400 Subject: [PATCH 26/73] Fixing print function --- testSplineKokkosBase.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/testSplineKokkosBase.cpp b/testSplineKokkosBase.cpp index 7bc261a..4a14762 100644 --- a/testSplineKokkosBase.cpp +++ b/testSplineKokkosBase.cpp @@ -6,15 +6,19 @@ template void printDView(Kokkos::View& dView) { - for (int i = 0; i < dView.extent(0); i++) { - std::cout << dView(i) << std::endl; + auto host_dView = Kokkos::create_mirror_view(dView); + Kokkos::deep_copy(host_dView, dView); + for (int i = 0; i < host_dView.extent(0); i++) { + std::cout << host_dView(i) << std::endl; } } template void printIView(Kokkos::View& iView) { - for (int i = 0; i < iView.extent(0); i++) { - std::cout << iView(i) << std::endl; + auto host_iView = Kokkos::create_mirror_view(iView); + Kokkos::deep_copy(host_iView, iView); + for (int i = 0; i < host_iView.extent(0); i++) { + std::cout << host_iView(i) << std::endl; } } @@ -33,6 +37,9 @@ void printSpline(BSplineKokkos spline) { iView = spline.getKnotsOffset(); std::cout << "Knots Offset" << std::endl; printIView(iView); + iView = spline.getOrder(); + std::cout << "Order" << std::endl; + printIView(iView); } int main(int argc, char* argv[]) { From e8617819873b4a037133bd926d45387ce49b5dea Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 24 Mar 2026 21:53:58 -0400 Subject: [PATCH 27/73] fixed multi spline constructor offset index --- BSplineKokkos.h | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index de96a1c..101e472 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -42,7 +42,7 @@ class BSplineKokkos { Kokkos::View cPOffsetV("CtrlPointsOffset", 1); auto host_cPOffsetV = Kokkos::create_mirror_view(cPOffsetV); - host_cPOffsetV(0) = 0; //Start of ctrlPts + host_cPOffsetV(0) = 2*ctrlPts_x.size(); //End of ctrlPts cPOffset = cPOffsetV; Kokkos::deep_copy(cPOffset, host_cPOffsetV); @@ -53,7 +53,7 @@ class BSplineKokkos { Kokkos::View knotsOffsetV("KnotsOffset", 1); auto host_knotsV = Kokkos::create_mirror_view(knotsV); auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); - host_knotsOffsetV(0) = 0; + host_knotsOffsetV(0) = 2*knots_x.size(); //End of knots for (int i = 0; i < knots_x.size(); i++) { host_knotsV(2*i) = knots_x[i]; @@ -97,8 +97,8 @@ class BSplineKokkos { //Input the offsets //Track space needed to allocate for ctrlPts & knots for (int i = 0; i < splines.size(); i++) { - cPOffSize += splines[i].getNumCtrlPts(); - kOffSize += splines[i].getNumKnots(); + cPOffSize += splines[i].getCPOffsetSize(); + kOffSize += splines[i].getKnotsOffsetSize(); ctrlPSize += splines[i].getCtrlPtsSize(); knotsSize += splines[i].getKnotsSize(); orderSize += splines[i].getOrder().extent(0); @@ -118,6 +118,9 @@ class BSplineKokkos { auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); auto host_weightsV = Kokkos::create_mirror_view(weightsV); + + std::cout << "ctrlPtsOffset size: " << cPOffsetV.extent(0)<< std::endl; + std::cout << "knotsOffset size: " << knotsOffsetV.extent(0) << std::endl; int oidx = 0; int cPidx = 0; int cOidx = 0; @@ -145,7 +148,6 @@ class BSplineKokkos { intView = splines[i].getCPOffset(); host_intView = Kokkos::create_mirror_view(intView); Kokkos::deep_copy(host_intView, intView); - host_intView = Kokkos::create_mirror_view(intView); for (int j = 0; j < host_intView.extent(0); j++) { std::cout << "\tctrlPtsOffset: " << host_intView(j) << std::endl; std::cout << "\tcpLast: " << cpLast << std::endl; @@ -154,7 +156,7 @@ class BSplineKokkos { } cOidx += host_intView.extent(0); - cpLast = host_cPOffsetV(cOidx-1)+(host_cPOffsetV(cOidx-1) - host_cPOffsetV(cOidx-2)); + cpLast += host_intView(host_intView.extent(0)-1); //Populate knots offset //Offset the offset by the last offset in the view @@ -165,7 +167,8 @@ class BSplineKokkos { host_knotsOffsetV(kOidx+j) = host_intView(j)+kLast; } kOidx += host_intView.extent(0); - kLast = host_knotsOffsetV(kOidx-1)+(host_knotsOffsetV(kOidx-1) - host_knotsOffsetV(kOidx-2)); + kLast += host_intView(host_intView.extent(0)-1); + //kLast = host_knotsOffsetV(kOidx-1)+(host_knotsOffsetV(kOidx-1) - host_knotsOffsetV(kOidx-2)); //Populate ctrlpts Kokkos::View doubleView = splines[i].getCtrlPts(); @@ -340,8 +343,8 @@ class BSplineKokkos { Kokkos::View get2ndD() const {return ctrlPts_2ndD;} - int getNumCtrlPts() const {return cPOffset.extent(0)/2;} - int getNumKnots() const {return knotsOffset.extent(0)/2;} + int getCPOffsetSize() const {return cPOffset.extent(0);} + int getKnotsOffsetSize() const {return knotsOffset.extent(0);} int getCtrlPtsSize() const {return ctrlPts.extent(0);} int getKnotsSize() const {return knots.extent(0);} int getWeightSize() const {return weights.extent(0);} From 865a5a3c4c4b637393de81804d4c43d405709d08 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Wed, 25 Mar 2026 10:22:23 -0400 Subject: [PATCH 28/73] Coeff function adapt with mirror views --- BSplineKokkos.h | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 101e472..0e3382f 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -212,7 +212,7 @@ class BSplineKokkos { Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); //TO DO: Work on calculate derivative coeff - //calculateDerivCoeff(); + calculateDerivCoeff(); } @@ -389,11 +389,12 @@ class BSplineKokkos { host_cP1stDOffsetV(0) = 0; auto host_cPOffset = Kokkos::create_mirror_view(cPOffset); + Kokkos::deep_copy(host_cPOffset, cPOffset); if (host_cPOffset.extent(0) > 1) { Kokkos::deep_copy(host_cPOffset, cPOffset); for (int i = 1; i < cPOffset.extent(0); i++) { - host_cP1stDOffsetV(i) = host_cPOffset(i)-1; - host_cP2ndDOffsetV(i) = host_cPOffset(i)-2; + host_cP1stDOffsetV(i) = host_cPOffset(i)-2; + host_cP2ndDOffsetV(i) = host_cPOffset(i)-4; std::cout << "1st: " << host_cP1stDOffsetV(i); std::cout << ", 2nd: " << host_cP2ndDOffsetV(i) << std::endl; } @@ -402,7 +403,7 @@ class BSplineKokkos { std::cout << "offset view populated" << std::endl; //We need to partition the x and y while we calculate the coefficient - /*int idx = 1; + int idx = 0; int oidx = 0; auto host_knots = Kokkos::create_mirror_view(knots); @@ -415,12 +416,39 @@ class BSplineKokkos { Kokkos::deep_copy(host_order, order); Kokkos::deep_copy(host_ctrlPts, ctrlPts); + std::cout << "Copied ctrlPts, knots, order" << std::endl; //We need to keep track of the indicies of the splines - for (int i = 1; i < ctrlPts.extent(0); i++) { + for (int i = 2; i < host_ctrlPts.extent(0); i++) { //Even indices stores all the x coordinates //Odd indices stores all the y coordinates + if (i == host_cPOffset(idx)) { + //This is the start of the next spline + oidx++; //Advance to get the next spline order + idx++; //Advace offset to next spline cut off + + } + double delta = double (host_order(oidx)-1)/(host_knots(i+host_order(oidx)-1)-host_knots(i)); + host_ctrlPts_1stDV(i-2) = (host_ctrlPts(i)-host_ctrlPts(i-2))*delta; + + } + + std::cout << "1stD coeff populated" << std::endl; + + Kokkos::View ctrlPts_2ndDV("ctrlPts2Derivative", ctrlPts.extent(0)-2*cPOffset.extent(0)); + auto host_ctrlPts_2ndDV = Kokkos::create_mirror_view(ctrlPts_2ndDV); + idx = 0; + oidx = 0; + for (int i = 2; i < host_ctrlPts_1stDV.extent(0); i++) { + if (i == host_cPOffset(idx)) { + oidx++; + idx++; + } + double delta = double(host_order(oidx)-2)/(host_knots(i+host_order(oidx)-1) - host_knots(i+1)); + host_ctrlPts_2ndDV(i-2) = (host_ctrlPts(i) - host_ctrlPts(i-2))*delta; + } + + - }*/ //Now that we interleave the data, we need to calculate the coordinates carefully /* @@ -473,7 +501,7 @@ class BSplineKokkos { } double delta = double((host_order(oidx)-2))/(host_knots(i+host_order(oidx)-1)-host_knots(i+1)); host_ctrlPts_2ndDV(i-1-(idx-1)) = host_ctrlPts_1stDV(i) - host_ctrlPts_1stDV(i-1)*delta; - } + }*/ Kokkos::deep_copy(cP1stDOffsetV, host_cP1stDOffsetV); Kokkos::deep_copy(cP2ndDOffsetV, host_cP2ndDOffsetV); @@ -483,7 +511,7 @@ class BSplineKokkos { ctrlPts_2ndD = ctrlPts_2ndDV; ctrlPts_1stD = ctrlPts_1stDV; cP1stDOffset = cP1stDOffsetV; - cP2ndDOffset = cP2ndDOffsetV;*/ + cP2ndDOffset = cP2ndDOffsetV; } private: From c794c9cc07a1872fe9bb3446ffb426ff0d625955 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Wed, 25 Mar 2026 11:32:01 -0400 Subject: [PATCH 29/73] eval1stD debug in progress --- BSplineKokkos.h | 96 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 33 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 0e3382f..b9b03cb 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -216,50 +216,65 @@ class BSplineKokkos { } - double evalFirstDeriv(double x, int splineo, char coor) const { + double evalFirstDeriv(double x, int splineo) const { //Find the order based on the spline number given - int lKnot = order(splineo)-1; + auto order_mv = Kokkos::create_mirror_view(order); + Kokkos::deep_copy(order_mv, order); + int lKnot = order_mv(splineo)-1; + std::cout << lKnot << std::endl; //Find the range that contains this spline //Need to make sure it is within the range of this spline + auto mv_knotsOffset = Kokkos::create_mirror_view(knotsOffset); + Kokkos::deep_copy(mv_knotsOffset, knotsOffset); int leftPt; int bound; - if (coor == 'x') { - //We are calculating the x component - leftPt = knotsOffset(2*splineo); - bound = knotsOffset(2*splineo+1); + + if (splineo == 0) { + leftPt = 0; + bound = mv_knotsOffset(splineo); } else { - leftPt = knotsOffset(2*splineo+1); - bound = knotsOffset(2*(splineo+1)); + //We are calculating the x component + leftPt = mv_knotsOffset(splineo-1); + bound = mv_knotsOffset(splineo); } + auto mv_knots = Kokkos::create_mirror_view(knots); + Kokkos::deep_copy(mv_knots, knots); + //Search within this range - while (knots(leftPt+1) < x && leftPt < bound) { - lKnot++; - leftPt++; + while (mv_knots(leftPt+1) < x && leftPt < bound) { + lKnot+=2; + leftPt+=2; } - int order_t = order(splineo)-1; + int order_t = order_mv(splineo)-1; //Copy to view; + auto mv_ctrlPts_1stD = Kokkos::create_mirror_view(ctrlPts_1stD); + Kokkos::deep_copy(mv_ctrlPts_1stD, ctrlPts_1stD); int idx = 0; Kokkos::View pts("pts", order_t); + auto mv_pts = Kokkos::create_mirror_view(pts); for (int i = leftPt; i < leftPt+order_t; i++) { - std::cout << i << "|" << ctrlPts_1stD(i) << std::endl; - pts(idx) = ctrlPts_1stD(i); + std::cout << i << "|" << mv_ctrlPts_1stD(i) << std::endl; + mv_pts(idx) = mv_ctrlPts_1stD(i); idx++; } + idx = 0; Kokkos::View localKnots("local knots", 2*order_t-2); + auto mv_localKnots = Kokkos::create_mirror_view(localKnots); for (int i = lKnot-order_t+2; i < lKnot+order_t+1; i++) { - localKnots(idx) = knots(i); + mv_localKnots(idx) = mv_knots(i); } + std::cout << "Local knots collection complete" << std::endl; Kokkos::parallel_for("1st derivative loop", order_t, KOKKOS_LAMBDA(int r) { for (int i = order_t-1; i >= r+1; i--) { - double aLeft = localKnots(i-1); - double aRight = localKnots(i+order_t-(r+1)-1); + double aLeft = mv_localKnots(i-1); + double aRight = mv_localKnots(i+order_t-(r+1)-1); double alpha; if (aLeft == aRight) { alpha = 0.; @@ -267,44 +282,58 @@ class BSplineKokkos { else { alpha = (x-aLeft)/(aRight-aLeft); } - pts(i) = (1. - alpha) * pts(i-1)+alpha*pts(i); + mv_pts(i) = (1. - alpha) * mv_pts(i-1)+alpha*mv_pts(i); } }); + std::cout << "Before deep copy of pts" << std::endl; + Kokkos::deep_copy(pts, mv_pts); + std::cout << "After deep copy of pts" << std::endl; return pts(order_t-1); } - double evalSecondDeriv(double x, int splineo, char coor) const { - if (order == 2) { + double evalSecondDeriv(double x, int splineo) const { + auto mv_order = Kokkos::create_mirror_view(order); + Kokkos::deep_copy(mv_order); + if (mv_order(splineo) == 2) { return 0; } - int lKnot = order(splineo)-1; + int lKnot = mv_order(splineo)-1; int leftPt; int bound; - if (coor == 'x') { - leftPt = (2*splineo); - bound = knotsOffset(2*splineo+1); + + auto mv_knotsOffset = Kokkos::create_mirror_view(knotsOffset); + Kokkos::deep_copy(mv_knotsOffset, knotsOffset); + if (splineo == 0) { + leftPt = 0; + bound = mv_knotsOffset(splineo); } else { - leftPt = knotsOffset(2*splineo+1); - bound = knotsOffset(2*(splineo+1)); + leftPt = mv_knotsOffset(splineo-1); + bound = mv_knotsOffset(splineo); } - while (knots(lKnot+1) < x && leftPt < bound) { - lKnot++; - leftPt++; + auto mv_knots = Kokkos::create_mirror_view(knots); + Kokkos::deep_copy(mv_knots, knots); + while (mv_knots(lKnot+1) < x && leftPt < bound) { + lKnot+=2; + leftPt+=2; } //Populate pts and local knot views - int order_t = order(splineo)-2; + int order_t = mv_order(splineo)-2; + auto mv_ctrlPts_2ndD = Kokkos::create_mirror_view(ctrlPts_2ndD); + Kokkos::deep_copy(mv_ctrlPts_2ndD, ctrlPts_2ndD); Kokkos::View pts("pts", order_t); + auto mv_pts = Kokkos::create_mirror_view(pts); for (int i = leftPt; i < leftPt+order_t; i++) { - pts(i-leftPt) = ctrlPts_2ndD(i); + mv_pts(i-leftPt) = mv_ctrlPts_2ndD(i); } Kokkos::View localKnots("localKnots", 2*order_t-2); int idx = 0; + auto mv_localKnots = Kokkos::create_mirror_view(localKnots); for (int i = lKnot-order_t+2; i < lKnot+order; i++) { - localKnots(idx) = knots(i); + mv_localKnots(idx) = mv_knots(i); idx++; } @@ -320,10 +349,11 @@ class BSplineKokkos { alpha = (x-aLeft)/(aRight-aLeft); } - pts(i) = (1. - alpha) * pts(i-1)+alpha*pts(i); + mv_pts(i) = (1. - alpha) * mv_pts(i-1)+alpha*mv_pts(i); } }); + Kokkos::deep_copy(pts, mv_pts); return pts(order_t-1); } From 22893398375c3e4a9024822e9efc7d8c457b2227 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Mon, 30 Mar 2026 22:57:39 -0400 Subject: [PATCH 30/73] Add serial spline & init SplineKokkos w/ same data --- CMakeLists.txt | 8 +++-- testSplineKokkosBase.cpp | 68 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b02254..7a0fb4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,6 +176,8 @@ set_tests_properties(testDiscoverTopo_L11pts PROPERTIES #THE FOLLOWING IS FOR BSPLINE_KOKKOS TESTS, MAY HAVE A LOT OF ERROR add_executable(testSplineKokkosBase testSplineKokkosBase.cpp) -target_link_libraries(testSplineKokkosBase PRIVATE splineKokkos Kokkos::kokkos) -add_test(NAME dummyBSplineKokkos - COMMAND ./testSplineKokkosBase) +target_link_libraries(testSplineKokkosBase PRIVATE modelGen2d curveReader splineKokkos Kokkos::kokkos splineInterp) +add_test(NAME testBSplineKokkosSerialStraightEdge + COMMAND ./testSplineKokkosBase ${testDataDir}/testCurveStrightLine.csv 9) +add_test(NAME testBSplineKokkosSerial_edge_2pts + COMMAND ./testSplineKokkosBase ${testDataDir}/testCurve2pts.csv 1) diff --git a/testSplineKokkosBase.cpp b/testSplineKokkosBase.cpp index 4a14762..829adc0 100644 --- a/testSplineKokkosBase.cpp +++ b/testSplineKokkosBase.cpp @@ -2,7 +2,16 @@ #include "BSplineKokkos.h" #include "BSpline.h" #include + +//These imports are from testSplineFitting.cc +#include "splineInterpolation.h" +#include "curveReader.h" +#include #include +#include +#include +#include +#include template void printDView(Kokkos::View& dView) { @@ -42,6 +51,13 @@ void printSpline(BSplineKokkos spline) { printIView(iView); } +void printVector(const std::string& name, std::vector& vector) { + std::cout << name << ": " << vector.size() << std::endl; + for (int i = 0; i < vector.size(); i++) { + std::cout << vector[i] << std::endl; + } +} + int main(int argc, char* argv[]) { Kokkos::initialize(argc, argv); { @@ -102,10 +118,56 @@ int main(int argc, char* argv[]) { std::cout << "Spline created from list of splines" << std::endl; printSpline(fromList); - //Testing for 1st Derivative - for (int i = 0; i < ex1.getCtrlPts().extent(0); i++) { - std::cout << ex1.evalFirstDeriv(ex1.getCtrlPts()(i), 0, 'x') << std::endl; + std::cout << "\n\nChecking derivative calculation against serial version" << std::endl; + std::cout << "Number of commandline arguments: " << argc << std::endl; + for (int i = 0; i < argc; i++) { + std::cout << argv[i] << std::endl; + } + if (argc != 3) { + //Check for the arguments needed + std::cerr<<"Input arguments: " << std::endl; + std::cerr << "input csv need these columns: "; + std::cerr << "x,y,z,isOnCurve,angle,isMdlVtx" << std::endl; + return 1; + } + + //Set up before using curve reader + std::string inputCSV = argv[1]; + int extensionPos = inputCSV.rfind("."); + int slashPos = inputCSV.rfind("/"); + std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); + double expectedCurveLength = std::stod(argv[2]); + auto curve = CurveReader::readCurveInfo(inputCSV); + + //Construct BSpline2d object + SplineInterp::BSpline2d serialBSP; + if (curve.x.size() == 2) { + serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); + } + else { + serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); } + + //Get the parameters and print the spline we initialized + std::vector ctrlPtsX, ctrlPtsY, knots, weight; + int order; + serialBSP.x.getpara(order, ctrlPtsX, knots, weight); + std::cout << "x component of the spline" << std::endl; + std::cout << "order: " << order << std::endl; + printVector("ctrlPtsX", ctrlPtsX); + printVector("knots", knots); + printVector("weight", weight); + serialBSP.y.getpara(order, ctrlPtsY, knots, weight); + std::cout << "y component of the spline" << std::endl; + std::cout << "order: " << order << std::endl; + printVector("ctrlPtsY", ctrlPtsY); + printVector("knots", knots); + printVector("weight", weight); + + //Now that we ensured that serial BSpline is created correctly we will now feed these data to our BSpline Kokkos Object + BSplineKokkos kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots, knots, weight); + printSpline(kokkosBSP); + } From 6c1196f220df13dffbfd6fbadbcfc80f931aff86 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 31 Mar 2026 12:20:07 -0400 Subject: [PATCH 31/73] Removed weights from constructors and member var --- BSplineKokkos.h | 97 +++---------------------------------------------- 1 file changed, 6 insertions(+), 91 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index b9b03cb..55ba410 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -15,7 +15,7 @@ class BSplineKokkos { using MemSpace = typename ExecutionSpace::memory_space; //Constructor for just 1 spline(Would this be used often?) - BSplineKokkos(int order_p, std::vector& ctrlPts_x, std::vector& ctrlPts_y, std::vector& knots_x, std::vector& knots_y, std::vector& weights_p) { + BSplineKokkos(int order_p, std::vector& ctrlPts_x, std::vector& ctrlPts_y, std::vector& knotsI) { //In the original implementation, we had the x and y components separated and was storing redundant knots information //The implementation now change to interleave the x and y coordinates //We store just 1 set of knots rather than 2 @@ -48,16 +48,15 @@ class BSplineKokkos { Kokkos::deep_copy(cPOffset, host_cPOffsetV); //Initialize knots and their offset - Kokkos::View knotsV("Knots", knots_x.size()*2); + Kokkos::View knotsV("Knots", knotsI.size()); Kokkos::View knotsOffsetV("KnotsOffset", 1); auto host_knotsV = Kokkos::create_mirror_view(knotsV); auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); - host_knotsOffsetV(0) = 2*knots_x.size(); //End of knots + host_knotsOffsetV(0) = knotsI.size(); //End of knots - for (int i = 0; i < knots_x.size(); i++) { - host_knotsV(2*i) = knots_x[i]; - host_knotsV((2*i)+1) = knots_y[i]; + for (int i = 0; i < knotsI.size(); i++) { + host_knotsV(i) = knotsI[i]; } knots = knotsV; @@ -66,15 +65,6 @@ class BSplineKokkos { knotsOffset = knotsOffsetV; Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); - //Copy the weights over - Kokkos::View weightsV("Weights", weights_p.size()); - auto host_weightsV = Kokkos::create_mirror_view(weightsV); - for (int i = 0; i < weights_p.size(); i++) { - host_weightsV(i) = weights_p[i]; - } - weights = weightsV; - Kokkos::deep_copy(weights, host_weightsV); - std::cout << "All good, before derivative coe" << std::endl; //Derivative coefficients calculateDerivCoeff(); @@ -92,7 +82,6 @@ class BSplineKokkos { int knotsSize = 0; int cPOffSize = 0; int kOffSize = 0; - int weightSize = 0; //Input the offsets //Track space needed to allocate for ctrlPts & knots @@ -102,7 +91,6 @@ class BSplineKokkos { ctrlPSize += splines[i].getCtrlPtsSize(); knotsSize += splines[i].getKnotsSize(); orderSize += splines[i].getOrder().extent(0); - weightSize += splines[i].getWeightSize(); } //Pre-Allocate space for views Kokkos::View orderV ("Order", orderSize); @@ -110,13 +98,11 @@ class BSplineKokkos { Kokkos::View cPOffsetV ("CtrlPtsOffset", cPOffSize); Kokkos::View knotsV("Knots", knotsSize); Kokkos::View knotsOffsetV ("KnotsOffset", kOffSize); - Kokkos::View weightsV("Weights", weightSize); auto host_orderV = Kokkos::create_mirror_view(orderV); auto host_ctrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); auto host_cPOffsetV = Kokkos::create_mirror_view(cPOffsetV); auto host_knotsV = Kokkos::create_mirror_view(knotsV); auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); - auto host_weightsV = Kokkos::create_mirror_view(weightsV); std::cout << "ctrlPtsOffset size: " << cPOffsetV.extent(0)<< std::endl; @@ -126,7 +112,6 @@ class BSplineKokkos { int cOidx = 0; int kidx = 0; int kOidx = 0; - int widx = 0; //Populate the views with data int cpLast = 0; @@ -185,22 +170,13 @@ class BSplineKokkos { for (int j = 0; j < host_doubleView.extent(0); j++) { host_knotsV(kidx+j) = host_doubleView(j); } - kidx += host_doubleView.extent(0); - //Populate the weights - doubleView = splines[i].getWeights(); - host_doubleView = Kokkos::create_mirror_view(doubleView); - Kokkos::deep_copy(host_doubleView, doubleView); - for (int j = 0; j < host_doubleView.extent(0); j++) { - host_weightsV(widx+j) = host_doubleView(j); - } - widx += host_doubleView.extent(0); + kidx += host_doubleView.extent(0); } //Update the member variables order = orderV; knots = knotsV; ctrlPts = ctrlPtsV; - weights = weightsV; cPOffset = cPOffsetV; knotsOffset = knotsOffsetV; //Copy the modification made from the host data to the device view @@ -208,7 +184,6 @@ class BSplineKokkos { Kokkos::deep_copy(knots, host_knotsV); Kokkos::deep_copy(ctrlPts, host_ctrlPtsV); Kokkos::deep_copy(cPOffset, host_cPOffsetV); - Kokkos::deep_copy(weights, host_weightsV); Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); //TO DO: Work on calculate derivative coeff @@ -366,7 +341,6 @@ class BSplineKokkos { Kokkos::View getOrder() const {return order;} Kokkos::View getCtrlPts() const {return ctrlPts;} Kokkos::View getKnots() const {return knots;} - Kokkos::View getWeights() const {return weights;} Kokkos::View getCPOffset() const {return cPOffset;} Kokkos::View getKnotsOffset() const {return knotsOffset;} Kokkos::View get1stD() const {return ctrlPts_1stD;} @@ -377,7 +351,6 @@ class BSplineKokkos { int getKnotsOffsetSize() const {return knotsOffset.extent(0);} int getCtrlPtsSize() const {return ctrlPts.extent(0);} int getKnotsSize() const {return knots.extent(0);} - int getWeightSize() const {return weights.extent(0);} int getOrderSize() const {return order.extent(0);} double getCtrlPtCoor(int BspIdx, int cPIdx, char coor) const { @@ -477,62 +450,6 @@ class BSplineKokkos { host_ctrlPts_2ndDV(i-2) = (host_ctrlPts(i) - host_ctrlPts(i-2))*delta; } - - - - //Now that we interleave the data, we need to calculate the coordinates carefully - /* - for (int i = 1; i < ctrlPts.extent(0); i++) { - if (i == host_cPOffset(idx)) { - //Do not calculate, delta will be based on both x and y - idx++; - if (idx % 2 != 0) { - oidx++; - //This is a different spline with different order - } - continue; - } - //std::cout << "Order: " << order(oidx) << std::endl; - //std::cout << "knots(i): " << knots(i) << std::endl; - //std::cout << "i+order(oidx)-1: " << knots(i+order(oidx)-1) << std::endl; - double delta = double(host_order(oidx) - 1)/(host_knots(i+host_order(oidx)-1)-host_knots(i)); - - //std::cout << ctrlPts(i-1) << "|" << ctrlPts(i) << std::endl; - - - //std::cout << "delta: " << delta << std::endl; - //std::cout <<"current point: "<< ctrlPts(i) << std::endl; - host_ctrlPts_1stDV(i-1-(idx-1)) = ((host_ctrlPts(i) - host_ctrlPts(i-1)*delta)); - //std::cout <<"cP coefficient: "<< ctrlPts_1stDV(i-1) << std::endl; - } - - std::cout << "end of 1stD coe calculation" << std::endl; - //Calculate second order derivative - Kokkos::View ctrlPts_2ndDV("ctrlPts2Derivative", ctrlPts.extent(0)-2*cPOffset.extent(0)); - - auto host_ctrlPts_2ndDV = Kokkos::create_mirror_view(ctrlPts_2ndDV); - - idx = 1; - oidx = 0; - - for (int i = 1; i < ctrlPts_1stDV.extent(0); i++) { - if (i == host_cP1stDOffsetV(idx)) { - idx++; - if (idx %2 != 0) { - oidx++; - } - continue; - } - if (host_order(oidx) == 2) { - //This will cause problem, it should be 0 anyway - host_ctrlPts_2ndDV(i-1-(idx-1)) = 0; - continue; - - } - double delta = double((host_order(oidx)-2))/(host_knots(i+host_order(oidx)-1)-host_knots(i+1)); - host_ctrlPts_2ndDV(i-1-(idx-1)) = host_ctrlPts_1stDV(i) - host_ctrlPts_1stDV(i-1)*delta; - }*/ - Kokkos::deep_copy(cP1stDOffsetV, host_cP1stDOffsetV); Kokkos::deep_copy(cP2ndDOffsetV, host_cP2ndDOffsetV); Kokkos::deep_copy(ctrlPts_1stDV, host_ctrlPts_1stDV); @@ -553,8 +470,6 @@ class BSplineKokkos { Kokkos::View cPOffset; Kokkos::View knots; Kokkos::View knotsOffset; - Kokkos::View weights; - //weight offset may be added later, not entirely sure for now //The 1st and 2nd derivatives Kokkos::View ctrlPts_1stD; From 246ed7552ce15c74d1385a24f25ea4b08c694e25 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 31 Mar 2026 13:02:18 -0400 Subject: [PATCH 32/73] Added serial 1st derivative test, wip for kokkos --- testSplineKokkosBase.cpp | 42 ++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/testSplineKokkosBase.cpp b/testSplineKokkosBase.cpp index 829adc0..1146bfc 100644 --- a/testSplineKokkosBase.cpp +++ b/testSplineKokkosBase.cpp @@ -77,11 +77,11 @@ int main(int argc, char* argv[]) { std::vector dummyCtrlPtsY{7.928, 12.18, 9.17, 6.67, 12.78}; std::vector dummyKnotsX{5.99, 8.98, 17.71, 21.1, 2.154, 9.17, 6.32}; - std::vector dummyKnotsY{2.85, 1.16, 0.82, 1.89, 9.82, 12.0, 7.19}; + //std::vector dummyKnotsY{2.85, 1.16, 0.82, 1.89, 9.82, 12.0, 7.19}; int dOrder = 2; - std::vector dummyWeights{0.87, 0.125, 0.03}; + //std::vector dummyWeights{0.87, 0.125, 0.03}; //Initialize 1 Kokkos Spline - BSplineKokkos ex1(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); + BSplineKokkos ex1(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX); //Check if we actually initialized with correct values std::cout << "ex1" << std::endl; @@ -93,10 +93,10 @@ int main(int argc, char* argv[]) { dummyCtrlPtsX.assign({1.20, 12.91, 7.11}); dummyCtrlPtsY.assign({3.31, 7.89, 9.12}); dummyKnotsX.assign({2.18, 5.56, 3.18, 16.15}); - dummyKnotsY.assign({1.971,4.12, 8.192, 12.11}); + //dummyKnotsY.assign({1.971,4.12, 8.192, 12.11}); dOrder = 3; - dummyWeights.assign({0.19, 0.27}); - BSplineKokkos ex2(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); + //dummyWeights.assign({0.19, 0.27}); + BSplineKokkos ex2(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX); splineList.push_back(ex2); std::cout << "ex2" << std::endl; printSpline(ex2); @@ -104,11 +104,9 @@ int main(int argc, char* argv[]) { dummyCtrlPtsX.assign({18.29, 12.12, 5.92, 7.182, 1.16}); dummyCtrlPtsY.assign({4.72, 5.78, 9.12, 1.29, 10.2}); dummyKnotsX.assign({4.34, 29.3, 18.7, 15.14, 16.87, 9.99}); - dummyKnotsY.assign({19.12, 10.21, 12.78, 8.12, 9.12, 12.12}); dOrder = 5; - dummyWeights.assign({0.12, 0.182, 0.98, 0.05}); std::cout << "\t\tSTART OF MULTISPLINE CREATION" << std::endl; - BSplineKokkos ex3(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX, dummyKnotsY, dummyWeights); + BSplineKokkos ex3(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX); splineList.push_back(ex3); std::cout << "ex3" << std::endl; printSpline(ex3); @@ -165,11 +163,31 @@ int main(int argc, char* argv[]) { printVector("weight", weight); //Now that we ensured that serial BSpline is created correctly we will now feed these data to our BSpline Kokkos Object - BSplineKokkos kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots, knots, weight); + BSplineKokkos kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); printSpline(kokkosBSP); + - - + //We can now test taking the first derivative + std::cout << "----Serial 1st derivative----" << std::endl; + for (int i = 0; i < ctrlPtsX.size(); i++) { + std::cout <<"Point: " << ctrlPtsX[i] << ", "; + std::cout << ctrlPtsY[i] << std::endl; + } + std::cout << "1st derivative, input x = 0: " << serialBSP.x.evalFirstDeriv(0) << ", " << serialBSP.y.evalFirstDeriv(0) << std::endl; + std::cout << "1st derivative, input x = 1: " << serialBSP.x.evalFirstDeriv(1) << ", " << serialBSP.y.evalFirstDeriv(1) << std::endl; + + std::cout << "----Kokkos 1st derivative----" << std::endl; + //Get and copy the control points here so we could print them + Kokkos::View dView = kokkosBSP.getCtrlPts(); + auto host_dView = Kokkos::create_mirror_view(dView); + Kokkos::deep_copy(host_dView, dView); + for (int i = 1; i < host_dView.extent(0); i+=2) { + std::cout <<"Point: " << host_dView(i-1) << ", " << host_dView(i) << std::endl; + } } + + std::cout << "1st derivative, input x = 0: " << kokkosBSP.eval1stDeriv(0, 0) << std::endl; + + std::cout << "1st derivative, input x = 1: " << kokkosBSP.eval1stDeriv(1, 0) << std::endl; Kokkos::finalize(); } From bcad4bfa7cef9c9fbfb5e89c78b176ea7c772f5b Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 31 Mar 2026 17:43:52 -0400 Subject: [PATCH 33/73] Fixing coef calculation in progress --- BSplineKokkos.h | 86 ++++++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 36 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 55ba410..f3e8cf6 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -191,82 +191,91 @@ class BSplineKokkos { } - double evalFirstDeriv(double x, int splineo) const { + double eval1stDeriv(double x, int splineo) const { //Find the order based on the spline number given auto order_mv = Kokkos::create_mirror_view(order); Kokkos::deep_copy(order_mv, order); int lKnot = order_mv(splineo)-1; - std::cout << lKnot << std::endl; + //std::cout << lKnot << std::endl; //Find the range that contains this spline //Need to make sure it is within the range of this spline - auto mv_knotsOffset = Kokkos::create_mirror_view(knotsOffset); - Kokkos::deep_copy(mv_knotsOffset, knotsOffset); - int leftPt; - int bound; - if (splineo == 0) { - leftPt = 0; - bound = mv_knotsOffset(splineo); - } - else { - //We are calculating the x component - leftPt = mv_knotsOffset(splineo-1); - bound = mv_knotsOffset(splineo); - } + int leftPtX = 0; //Even indicies are x coordinates + int leftPtY = 1; //Odd indicies are y coordinates + + //Find the boundary to the current spline control points auto mv_knots = Kokkos::create_mirror_view(knots); Kokkos::deep_copy(mv_knots, knots); //Search within this range - while (mv_knots(leftPt+1) < x && leftPt < bound) { + while (mv_knots(lKnot+1) < x) { lKnot+=2; - leftPt+=2; + leftPtX+=2; //Increment xpts + leftPtY+=2; //Increment ypts } int order_t = order_mv(splineo)-1; - //Copy to view; + //Copy our previously calculated coefficient auto mv_ctrlPts_1stD = Kokkos::create_mirror_view(ctrlPts_1stD); Kokkos::deep_copy(mv_ctrlPts_1stD, ctrlPts_1stD); + int idx = 0; - Kokkos::View pts("pts", order_t); - auto mv_pts = Kokkos::create_mirror_view(pts); - for (int i = leftPt; i < leftPt+order_t; i++) { - std::cout << i << "|" << mv_ctrlPts_1stD(i) << std::endl; - mv_pts(idx) = mv_ctrlPts_1stD(i); + Kokkos::View ptsX("ptsX", order_t); + auto mv_ptsX = Kokkos::create_mirror_view(ptsX); + Kokkos::View ptsY("ptsY", order_t); + auto mv_ptsY = Kokkos::create_mirror_view(ptsY); + for (int i = leftPtX; i < leftPtX+order_t-1; i+=2) { + //std::cout << i << "|" << mv_ctrlPts_1stD(i) << std::endl; + mv_ptsX(idx) = mv_ctrlPts_1stD(i); + mv_ptsY(idx) = mv_ctrlPts_1stD(i+1); idx++; } + for (int i = 0; i < mv_ptsX.extent(0); i++) { + std::cout << mv_ptsX(i) << std::endl; + } + std::cout << "|" << std::endl; + + //We only need 1 copy of the local knots idx = 0; Kokkos::View localKnots("local knots", 2*order_t-2); auto mv_localKnots = Kokkos::create_mirror_view(localKnots); for (int i = lKnot-order_t+2; i < lKnot+order_t+1; i++) { mv_localKnots(idx) = mv_knots(i); } - std::cout << "Local knots collection complete" << std::endl; + //std::cout << "Local knots collection complete" << std::endl; + + //Copy allocated value back to device + Kokkos::deep_copy(localKnots, mv_localKnots); + Kokkos::deep_copy(ptsX, mv_ptsX); Kokkos::parallel_for("1st derivative loop", order_t, KOKKOS_LAMBDA(int r) { for (int i = order_t-1; i >= r+1; i--) { - double aLeft = mv_localKnots(i-1); - double aRight = mv_localKnots(i+order_t-(r+1)-1); + double aLeft = localKnots(i-1); + double aRight = localKnots(i+order_t-(r+1)-1); double alpha; if (aLeft == aRight) { alpha = 0.; } else { alpha = (x-aLeft)/(aRight-aLeft); - } - mv_pts(i) = (1. - alpha) * mv_pts(i-1)+alpha*mv_pts(i); + } + ptsX(i) = (1. - alpha) * ptsX(i-1)+alpha*ptsX(i); } }); - std::cout << "Before deep copy of pts" << std::endl; - Kokkos::deep_copy(pts, mv_pts); - std::cout << "After deep copy of pts" << std::endl; - return pts(order_t-1); + //std::cout << "Before deep copy of pts" << std::endl; + Kokkos::deep_copy(mv_ptsX, ptsX); + //std::cout << "After deep copy of pts" << std::endl; + for (int i = 0; i < mv_ptsX.extent(0); i++) { + std::cout << mv_ptsX(i) << std::endl; + } + return mv_ptsX(order_t-1); } - double evalSecondDeriv(double x, int splineo) const { + double eval2ndDeriv(double x, int splineo) const { auto mv_order = Kokkos::create_mirror_view(order); Kokkos::deep_copy(mv_order); if (mv_order(splineo) == 2) { @@ -377,19 +386,17 @@ class BSplineKokkos { //Allocate the space std::cout << "calculating derivative coeff" << std::endl; - Kokkos::View ctrlPts_1stDV("ctrlPts1Derivative", ctrlPts.extent(0)-cPOffset.extent(0)); + Kokkos::View ctrlPts_1stDV("ctrlPts1Derivative", ctrlPts.extent(0)-(2*cPOffset.extent(0))); Kokkos::View cP1stDOffsetV("ctrlPts1DerivativeOffset", cPOffset.extent(0)); Kokkos::View cP2ndDOffsetV("ctrlPts2DerivativeOffset", cPOffset.extent(0)); auto host_cP2ndDOffsetV = Kokkos::create_mirror_view(cP2ndDOffsetV); auto host_cP1stDOffsetV = Kokkos::create_mirror_view(cP1stDOffsetV); - host_cP2ndDOffsetV(0) = 0; std::cout << "offset views and 1stctrlPts views construct" << std::endl; //Adjust the offset to include be 1 & 2 less than the ctrlPtsOffset - host_cP1stDOffsetV(0) = 0; auto host_cPOffset = Kokkos::create_mirror_view(cPOffset); Kokkos::deep_copy(host_cPOffset, cPOffset); @@ -402,6 +409,10 @@ class BSplineKokkos { std::cout << ", 2nd: " << host_cP2ndDOffsetV(i) << std::endl; } } + else { + host_cP1stDOffsetV(0) = host_cPOffset(0)-2; + host_cP2ndDOffsetV(0) = host_cPOffset(0)-4; + } std::cout << "offset view populated" << std::endl; @@ -432,7 +443,10 @@ class BSplineKokkos { } double delta = double (host_order(oidx)-1)/(host_knots(i+host_order(oidx)-1)-host_knots(i)); host_ctrlPts_1stDV(i-2) = (host_ctrlPts(i)-host_ctrlPts(i-2))*delta; + } + for (int i = 0; i < host_ctrlPts_1stDV.extent(0); i++) { + std::cout << "1stD Coeff: "<< host_ctrlPts_1stDV(i) << std::endl; } std::cout << "1stD coeff populated" << std::endl; From b2a667fd67d5abfddfd0fd4031350a210e0808d5 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Wed, 1 Apr 2026 00:53:46 -0400 Subject: [PATCH 34/73] Fixed deriv coef calculation for 1st deriv --- BSplineKokkos.h | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index f3e8cf6..2f40b96 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -405,8 +405,8 @@ class BSplineKokkos { for (int i = 1; i < cPOffset.extent(0); i++) { host_cP1stDOffsetV(i) = host_cPOffset(i)-2; host_cP2ndDOffsetV(i) = host_cPOffset(i)-4; - std::cout << "1st: " << host_cP1stDOffsetV(i); - std::cout << ", 2nd: " << host_cP2ndDOffsetV(i) << std::endl; + //std::cout << "1st: " << host_cP1stDOffsetV(i); + //std::cout << ", 2nd: " << host_cP2ndDOffsetV(i) << std::endl; } } else { @@ -419,6 +419,8 @@ class BSplineKokkos { //We need to partition the x and y while we calculate the coefficient int idx = 0; int oidx = 0; + double deltaHold = 0; + int kidx = 2; auto host_knots = Kokkos::create_mirror_view(knots); auto host_order = Kokkos::create_mirror_view(order); @@ -432,21 +434,21 @@ class BSplineKokkos { std::cout << "Copied ctrlPts, knots, order" << std::endl; //We need to keep track of the indicies of the splines + //We ignore the first ctrl point, starting at idx = 2 for (int i = 2; i < host_ctrlPts.extent(0); i++) { //Even indices stores all the x coordinates //Odd indices stores all the y coordinates - if (i == host_cPOffset(idx)) { - //This is the start of the next spline - oidx++; //Advance to get the next spline order - idx++; //Advace offset to next spline cut off - + if (i == host_cPOffset(idx)) { oidx++; + idx++; + } + if (i%2==0) { + double delta = double (host_order(oidx)-1)/(host_knots(kidx+host_order(oidx)-2)-host_knots(kidx-1)); + deltaHold = delta; + kidx++; } - double delta = double (host_order(oidx)-1)/(host_knots(i+host_order(oidx)-1)-host_knots(i)); - host_ctrlPts_1stDV(i-2) = (host_ctrlPts(i)-host_ctrlPts(i-2))*delta; - } - - for (int i = 0; i < host_ctrlPts_1stDV.extent(0); i++) { - std::cout << "1stD Coeff: "<< host_ctrlPts_1stDV(i) << std::endl; + //std::cout << "deltaHold: " << deltaHold << std::endl; + //std::cout << "ctrlPts: "<< host_ctrlPts(i) << ", " << host_ctrlPts(i-2) << std::endl; + host_ctrlPts_1stDV(i-2) = (host_ctrlPts(i)-host_ctrlPts(i-2))*deltaHold; } std::cout << "1stD coeff populated" << std::endl; @@ -460,7 +462,7 @@ class BSplineKokkos { oidx++; idx++; } - double delta = double(host_order(oidx)-2)/(host_knots(i+host_order(oidx)-1) - host_knots(i+1)); + double delta = double(host_order(oidx)-2)/(host_knots(i+host_order(oidx)-1) - host_knots(i)); host_ctrlPts_2ndDV(i-2) = (host_ctrlPts(i) - host_ctrlPts(i-2))*delta; } From 9e11d6ec20b0db6375d5bc3c6781093c1be9fd25 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Wed, 1 Apr 2026 01:04:03 -0400 Subject: [PATCH 35/73] Added simple 2nd deriv test against serial version --- testSplineKokkosBase.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/testSplineKokkosBase.cpp b/testSplineKokkosBase.cpp index 1146bfc..9bc55e1 100644 --- a/testSplineKokkosBase.cpp +++ b/testSplineKokkosBase.cpp @@ -180,14 +180,30 @@ int main(int argc, char* argv[]) { //Get and copy the control points here so we could print them Kokkos::View dView = kokkosBSP.getCtrlPts(); auto host_dView = Kokkos::create_mirror_view(dView); - Kokkos::deep_copy(host_dView, dView); + Kokkos::deep_copy(host_dView, dView); for (int i = 1; i < host_dView.extent(0); i+=2) { std::cout <<"Point: " << host_dView(i-1) << ", " << host_dView(i) << std::endl; } - } + std::cout << "1st derivative, input x = 0: " << kokkosBSP.eval1stDeriv(0, 0) << std::endl; + + std::cout << "1st derivative, input x = 1: " << kokkosBSP.eval1stDeriv(1, 0) << std::endl; + + std::cout << "----Serial 2nd derivative----" << std::endl; + std::cout << "2nd derivative, input x = 0: " << serialBSP.x.evalSecondDeriv(0) << ", " << serialBSP.y.evalSecondDeriv(0) << std::endl; + std::cout << "2nd derivative, input x = 1: " << serialBSP.x.evalSecondDeriv(1) << ", " << serialBSP.y.evalSecondDeriv(1) << std::endl; + + std::cout << "----Kokkos 2nd derivative----" << std::endl; + //Get and copy the control points here so we could print them + dView = kokkosBSP.getCtrlPts(); + host_dView = Kokkos::create_mirror_view(dView); + Kokkos::deep_copy(host_dView, dView); + for (int i = 1; i < host_dView.extent(0); i+=2) { + std::cout <<"Point: " << host_dView(i-1) << ", " << host_dView(i) << std::endl; + } + std::cout << "2nd derivative, input x = 0: " << kokkosBSP.eval2ndDeriv(0, 0) << std::endl; - std::cout << "1st derivative, input x = 0: " << kokkosBSP.eval1stDeriv(0, 0) << std::endl; + std::cout << "2nd derivative, input x = 1: " << kokkosBSP.eval2ndDeriv(1, 0) << std::endl; - std::cout << "1st derivative, input x = 1: " << kokkosBSP.eval1stDeriv(1, 0) << std::endl; + } Kokkos::finalize(); } From dd470d58544f63f28ffa0f1afcf7f5cbaba1f527 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Wed, 1 Apr 2026 10:31:48 -0400 Subject: [PATCH 36/73] Ongoing fix for 2nd deriv coeff --- BSplineKokkos.h | 65 +++++++++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 2f40b96..2d68ae1 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -277,50 +277,67 @@ class BSplineKokkos { double eval2ndDeriv(double x, int splineo) const { auto mv_order = Kokkos::create_mirror_view(order); - Kokkos::deep_copy(mv_order); + Kokkos::deep_copy(mv_order, order); if (mv_order(splineo) == 2) { return 0; } - + //Get the left knot, leftPtX, leftPtY int lKnot = mv_order(splineo)-1; - int leftPt; - int bound; - + int leftPtX = 0; + int leftPtY = 1; + + //Make sure that we did not go over to the next spline auto mv_knotsOffset = Kokkos::create_mirror_view(knotsOffset); Kokkos::deep_copy(mv_knotsOffset, knotsOffset); - if (splineo == 0) { - leftPt = 0; - bound = mv_knotsOffset(splineo); - } else { - leftPt = mv_knotsOffset(splineo-1); - bound = mv_knotsOffset(splineo); - } + + int bound = mv_knotsOffset(splineo); auto mv_knots = Kokkos::create_mirror_view(knots); Kokkos::deep_copy(mv_knots, knots); - while (mv_knots(lKnot+1) < x && leftPt < bound) { + while (mv_knots(lKnot+1) < x) { lKnot+=2; - leftPt+=2; + leftPtX+=2; + leftPtY+=2; + if (lKnot == bound-1) { + break; + } } //Populate pts and local knot views int order_t = mv_order(splineo)-2; auto mv_ctrlPts_2ndD = Kokkos::create_mirror_view(ctrlPts_2ndD); + int idx = 0; Kokkos::deep_copy(mv_ctrlPts_2ndD, ctrlPts_2ndD); - Kokkos::View pts("pts", order_t); - auto mv_pts = Kokkos::create_mirror_view(pts); - for (int i = leftPt; i < leftPt+order_t; i++) { - mv_pts(i-leftPt) = mv_ctrlPts_2ndD(i); + + std::cout << "Second derivative coeff" << std::endl; + for (int i = 0; i < mv_ctrlPts_2ndD.extent(0); i++) { + std::cout << mv_ctrlPts_2ndD(i) << std::endl; + } + std::cout << "------------------------" << std::endl; + Kokkos::View ptsX("ptsX", order_t); + Kokkos::View ptsY("ptsY", order_t); + auto mv_ptsX = Kokkos::create_mirror_view(ptsX); + auto mv_ptsY = Kokkos::create_mirror_view(ptsY); + + for (int i = leftPtX; i < leftPtX+order_t; i+=2) { + mv_ptsX(idx) = mv_ctrlPts_2ndD(i); + mv_ptsY(idx) = mv_ctrlPts_2ndD(i+1); } + //Start populating the local knots + idx = 0; Kokkos::View localKnots("localKnots", 2*order_t-2); - int idx = 0; auto mv_localKnots = Kokkos::create_mirror_view(localKnots); - for (int i = lKnot-order_t+2; i < lKnot+order; i++) { + for (int i = lKnot-order_t+2; i < lKnot+order_t; i++) { mv_localKnots(idx) = mv_knots(i); idx++; } + //Copy the data back to device + Kokkos::deep_copy(localKnots, mv_localKnots); + Kokkos::deep_copy(ptsX, mv_ptsX); + Kokkos::deep_copy(ptsY, mv_ptsY); + Kokkos::parallel_for ("2nd derivative loop", order_t, KOKKOS_LAMBDA(int r){ for (int i = order_t-1; i >= r+1; i--) { double aLeft = localKnots(i-1); @@ -333,12 +350,12 @@ class BSplineKokkos { alpha = (x-aLeft)/(aRight-aLeft); } - mv_pts(i) = (1. - alpha) * mv_pts(i-1)+alpha*mv_pts(i); + ptsX(i) = (1. - alpha) * ptsX(i-1)+alpha*ptsX(i); } }); - Kokkos::deep_copy(pts, mv_pts); - return pts(order_t-1); + Kokkos::deep_copy(mv_ptsX, ptsX); + return mv_ptsX(order_t-1); } @@ -453,7 +470,7 @@ class BSplineKokkos { std::cout << "1stD coeff populated" << std::endl; - Kokkos::View ctrlPts_2ndDV("ctrlPts2Derivative", ctrlPts.extent(0)-2*cPOffset.extent(0)); + Kokkos::View ctrlPts_2ndDV("ctrlPts2Derivative", ctrlPts.extent(0)-(2*cPOffset.extent(0))-2); auto host_ctrlPts_2ndDV = Kokkos::create_mirror_view(ctrlPts_2ndDV); idx = 0; oidx = 0; From 8e7bc8a06e2758f45ef0958a3ea237b5f72d9f2a Mon Sep 17 00:00:00 2001 From: Hsieh Date: Sun, 5 Apr 2026 15:56:56 -0400 Subject: [PATCH 37/73] Added tests for kokkos 1st derivative --- testKokkos1stDerivative.cpp | 286 ++++++++++++++++++++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 testKokkos1stDerivative.cpp diff --git a/testKokkos1stDerivative.cpp b/testKokkos1stDerivative.cpp new file mode 100644 index 0000000..457908f --- /dev/null +++ b/testKokkos1stDerivative.cpp @@ -0,0 +1,286 @@ +#include +#include "BSplineKokkos.h" +#include "BSpline.h" +#include + +//These imports are from testSplineFitting.cc +#include "splineInterpolation.h" +#include "curveReader.h" +#include +#include +#include +#include +#include +#include + + +template +void printDView(Kokkos::View& dView) { + auto host_dView = Kokkos::create_mirror_view(dView); + Kokkos::deep_copy(host_dView, dView); + for (int i = 0; i < host_dView.extent(0); i++) { + std::cout << host_dView(i) << std::endl; + } +} + +template +void printIView(Kokkos::View& iView) { + auto host_iView = Kokkos::create_mirror_view(iView); + Kokkos::deep_copy(host_iView, iView); + for (int i = 0; i < host_iView.extent(0); i++) { + std::cout << host_iView(i) << std::endl; + } +} + +template +void printSpline(BSplineKokkos spline) { + std::cout << "Spline content" << std::endl; + Kokkos::View dView = spline.getCtrlPts(); + std::cout << "CtrlPts" << std::endl; + printDView(dView); + Kokkos::View iView = spline.getCPOffset(); + std::cout << "CtrlPts Offset" << std::endl; + printIView(iView); + dView = spline.getKnots(); + std::cout << "Knots" << std::endl; + printDView(dView); + iView = spline.getKnotsOffset(); + std::cout << "Knots Offset" << std::endl; + printIView(iView); + iView = spline.getOrder(); + std::cout << "Order" << std::endl; + printIView(iView); +} + +void printVector(const std::string& name, std::vector& vector) { + std::cout << name << ": " << vector.size() << std::endl; + for (int i = 0; i < vector.size(); i++) { + std::cout << vector[i] << std::endl; + } +} + +double epsilon = 0.005; + +int main(int argc, char* argv[]) { + Kokkos::initialize(argc, argv); + { + + //Check for what memory space we should use + //Sticking to just cuda space or host space for now + + #ifdef KOKKOS_ENABLE_CUDA + #define MemSpace Kokkos::CudaSpace + #endif + #ifndef MemSpace + #define MemSpace Kokkos::HostSpace + #endif + + using ExecutionSpace = MemSpace::execution_space; + + + if (argc != 3) { //Check for the arguments needed std::cerr<<"Input arguments: " << std::endl; std::cerr << "input csv need these columns: "; + std::cerr << "x,y,z,isOnCurve,angle,isMdlVtx" << std::endl; + return 1; } + std::string inputCSV = argv[1]; + int extensionPos = inputCSV.rfind("."); + int slashPos = inputCSV.rfind("/"); + std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); + double expectedCurveLength = std::stod(argv[2]); + auto curve = CurveReader::readCurveInfo(inputCSV); + + //Construct BSpline2d object + SplineInterp::BSpline2d serialBSP; + if (curve.x.size() == 2) { + serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); + } else { + serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); + } + + std::vector ctrlPtsX, ctrlPtsY, knots, weight; + int order; + + //Get the info from serial spline, we will feed this to kokkos spline + serialBSP.x.getpara(order, ctrlPtsX, knots, weight); + serialBSP.y.getpara(order, ctrlPtsY, knots, weight); + + BSplineKokkos kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); + //printSpline(kokkosBSP); + + + /*INITALIZATION COMPLETE, TEST STARTS BELOW*/ + //TEST 1 HERE + std::cout << "TEST 1, EVAL AT 0" << std::endl; + double derivX = serialBSP.x.evalFirstDeriv(0); + double derivY = serialBSP.y.evalFirstDeriv(0); + std::cout << "SERIAL: 1st derivative, input x = 0: " << derivX << ", " << derivY << std::endl; + + std::vector kokkos1stDeriv = kokkosBSP.eval1stDeriv(0, 0); + double kokkosDerivX = kokkos1stDeriv[0]; + double kokkosDerivY = kokkos1stDeriv[1]; + + double derivXDiff = derivX - kokkosDerivX; + double derivYDiff = derivY - kokkosDerivY; + std::cout << "KOKKOS: 1st derivative, input x = 0: " << kokkosDerivX <<", " << kokkosDerivY << std::endl; + + std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; + + + //TEST 2 HERE + std::cout << "TEST 2, EVAL AT 0.2" << std::endl; + derivX = serialBSP.x.evalFirstDeriv(0.2); + derivY = serialBSP.y.evalFirstDeriv(0.2); + std::cout << "SERIAL: 1st derivative, input x = 0.2: " << derivX << ", " << derivY << std::endl; + kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.2, 0); + kokkosDerivX = kokkos1stDeriv[0]; + kokkosDerivY = kokkos1stDeriv[1]; + + derivXDiff = derivX - kokkosDerivX; + derivYDiff = derivY - kokkosDerivY; + + std::cout << "KOKKOS: 1st derivative, input x = 0.2: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; + + std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; + + + //TEST 3 + std::cout << "TEST 3: EVAL AT 0.41" << std::endl; + derivX = serialBSP.x.evalFirstDeriv(0.41); + derivY = serialBSP.y.evalFirstDeriv(0.41); + std::cout << "SERIAL: 1st derivative, input x = 0.41: " << derivX << ", " << derivY << std::endl; + + kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.41, 0); + kokkosDerivX = kokkos1stDeriv[0]; + kokkosDerivY = kokkos1stDeriv[1]; + + derivXDiff = derivX - kokkosDerivX; + derivYDiff = derivY - kokkosDerivY; + + std::cout << "KOKKOS: 1st derivative, input x = 0.41: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; + + std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; + + + //TEST 4 + std::cout << "TEST 4: EVAL AT 0.5" << std::endl; + derivX = serialBSP.x.evalFirstDeriv(0.5); + derivY = serialBSP.y.evalFirstDeriv(0.5); + std::cout << "SERIAL: 1st derivative, input x = 0.5: " << derivX << ", " << derivY << std::endl; + + kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.5, 0); + kokkosDerivX = kokkos1stDeriv[0]; + kokkosDerivY = kokkos1stDeriv[1]; + + derivXDiff = derivX - kokkosDerivX; + derivYDiff = derivY - kokkosDerivY; + + std::cout << "KOKKOS: 1st derivative, input x = 0.5: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; + + std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; + + //TEST 5 + std::cout << "TEST 5: EVAL AT 0.66" << std::endl; + derivX = serialBSP.x.evalFirstDeriv(0.66); + derivY = serialBSP.y.evalFirstDeriv(0.66); + std::cout << "SERIAL: 1st derivative, input x = 0.66: " << derivX << ", " << derivY << std::endl; + + kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.66, 0); + kokkosDerivX = kokkos1stDeriv[0]; + kokkosDerivY = kokkos1stDeriv[1]; + + derivXDiff = derivX - kokkosDerivX; + derivYDiff = derivY - kokkosDerivY; + + std::cout << "KOKKOS: 1st derivative, input x = 0.66: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; + + std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; + + + //TEST 6 + std::cout << "Test 6: EVAL AT 0.73" << std::endl; + derivX = serialBSP.x.evalFirstDeriv(0.73); + derivY = serialBSP.y.evalFirstDeriv(0.73); + std::cout << "SERIAL: 1st derivative, input x = 0.73: " << derivX << ", " << derivY << std::endl; + kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.73, 0); + kokkosDerivX = kokkos1stDeriv[0]; + kokkosDerivY = kokkos1stDeriv[1]; + + derivXDiff = derivX - kokkosDerivX; + derivYDiff = derivY - kokkosDerivY; + + std::cout << "KOKKOS: 1st derivative, input x = 0.73: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; + + std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; + + + //TEST 7 + std::cout << "TEST 7: EVAL AT 0.75" << std::endl; + derivX = serialBSP.x.evalFirstDeriv(0.75); + derivY = serialBSP.y.evalFirstDeriv(0.75); + std::cout << "SERIAL: 1st derivative, input x = 0.75: " << derivX << ", " << derivY << std::endl; + kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.75, 0); + kokkosDerivX = kokkos1stDeriv[0]; + kokkosDerivY = kokkos1stDeriv[1]; + + derivXDiff = derivX - kokkosDerivX; + derivYDiff = derivY - kokkosDerivY; + + std::cout << "KOKKOS: 1st derivative, input x = 0.75: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; + + std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; + + + //TEST 8 + std::cout << "TEST 8: EVAL AT 0.89" << std::endl; + derivX = serialBSP.x.evalFirstDeriv(0.89); + derivY = serialBSP.y.evalFirstDeriv(0.89); + std::cout << "SERIAL: 1st derivative, input x = 0.89: " << derivX << ", " << derivY << std::endl; + + kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.89, 0); + kokkosDerivX = kokkos1stDeriv[0]; + kokkosDerivY = kokkos1stDeriv[1]; + + derivXDiff = derivX - kokkosDerivX; + derivYDiff = derivY - kokkosDerivY; + + std::cout << "KOKKOS: 1st derivative, input x = 0.89: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; + + std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; + + + //TEST 9 + std::cout << "TEST 9: EVAL AT 0.94" << std::endl; + derivX = serialBSP.x.evalFirstDeriv(0.94); + derivY = serialBSP.y.evalFirstDeriv(0.94); + std::cout << "SERIAL: 1st derivative, input x = 0.94: " << derivX << ", " << derivY << std::endl; + kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.94, 0); + kokkosDerivX = kokkos1stDeriv[0]; + kokkosDerivY = kokkos1stDeriv[1]; + + derivXDiff = derivX - kokkosDerivX; + derivYDiff = derivY - kokkosDerivY; + + std::cout << "KOKKOS: 1st derivative, input x = 0.94: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; + + std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; + + + //TEST 10 + std::cout << "TEST 10: EVAL AT 1" << std::endl; + derivX = serialBSP.x.evalFirstDeriv(1); + derivY = serialBSP.y.evalFirstDeriv(1); + std::cout << "SERIAL: 1st derivative, input x = 1: " << derivX << ", " << derivY << std::endl; + + kokkos1stDeriv = kokkosBSP.eval1stDeriv(1, 0); + kokkosDerivX = kokkos1stDeriv[0]; + kokkosDerivY = kokkos1stDeriv[1]; + + derivXDiff = derivX - kokkosDerivX; + derivYDiff = derivY - kokkosDerivY; + + std::cout << "KOKKOS: 1st derivative, input x = 1: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; + + std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; + + } + Kokkos::finalize(); +} From 5e4439b99be620b2d4349d9d9815475cb0be9810 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Sun, 5 Apr 2026 15:58:22 -0400 Subject: [PATCH 38/73] Added test to CMakeLists, 1stDeriv returns x&y res --- BSplineKokkos.h | 18 ++++++++++++------ CMakeLists.txt | 13 +++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 2d68ae1..5addf48 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -191,7 +191,7 @@ class BSplineKokkos { } - double eval1stDeriv(double x, int splineo) const { + std::vector eval1stDeriv(double x, int splineo) const { //Find the order based on the spline number given auto order_mv = Kokkos::create_mirror_view(order); Kokkos::deep_copy(order_mv, order); @@ -234,10 +234,10 @@ class BSplineKokkos { idx++; } - for (int i = 0; i < mv_ptsX.extent(0); i++) { + /*for (int i = 0; i < mv_ptsX.extent(0); i++) { std::cout << mv_ptsX(i) << std::endl; } - std::cout << "|" << std::endl; + std::cout << "|" << std::endl;*/ //We only need 1 copy of the local knots idx = 0; @@ -251,6 +251,7 @@ class BSplineKokkos { //Copy allocated value back to device Kokkos::deep_copy(localKnots, mv_localKnots); Kokkos::deep_copy(ptsX, mv_ptsX); + Kokkos::deep_copy(ptsY, mv_ptsY); Kokkos::parallel_for("1st derivative loop", order_t, KOKKOS_LAMBDA(int r) { for (int i = order_t-1; i >= r+1; i--) { @@ -264,15 +265,20 @@ class BSplineKokkos { alpha = (x-aLeft)/(aRight-aLeft); } ptsX(i) = (1. - alpha) * ptsX(i-1)+alpha*ptsX(i); + ptsY(i) = (1. - alpha) * ptsY(i-1)+alpha*ptsY(i); } }); //std::cout << "Before deep copy of pts" << std::endl; Kokkos::deep_copy(mv_ptsX, ptsX); + Kokkos::deep_copy(mv_ptsY, ptsY); //std::cout << "After deep copy of pts" << std::endl; - for (int i = 0; i < mv_ptsX.extent(0); i++) { + /*for (int i = 0; i < mv_ptsX.extent(0); i++) { std::cout << mv_ptsX(i) << std::endl; - } - return mv_ptsX(order_t-1); + }*/ + std::vector result; + result.push_back(mv_ptsX(order_t-1)); + result.push_back(mv_ptsY(order_t-1)); + return result; } double eval2ndDeriv(double x, int splineo) const { diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a0fb4f..0c7f769 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -181,3 +181,16 @@ add_test(NAME testBSplineKokkosSerialStraightEdge COMMAND ./testSplineKokkosBase ${testDataDir}/testCurveStrightLine.csv 9) add_test(NAME testBSplineKokkosSerial_edge_2pts COMMAND ./testSplineKokkosBase ${testDataDir}/testCurve2pts.csv 1) + +#TEST FOR BSPLINEKOKKOS 1ST DERIVATIVE +add_executable(testKokkos1stDerivative testKokkos1stDerivative.cpp) +target_link_libraries(testKokkos1stDerivative PRIVATE modelGen2d curveReader splineKokkos Kokkos::kokkos splineInterp) + +add_test(NAME testKokkos1stDerivativeStraightEdge + COMMAND ./testKokkos1stDerivative contour_test_data/testCurveStrightLine.csv 9) + +add_test(NAME testKokkos1stDerivativeEdge2Pts + COMMAND ./testKokkos1stDerivative contour_test_data/testCurve2pts.csv 1) + + + From 9e997594be895e8014975b33dc89473624ae44b3 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 7 Apr 2026 21:57:21 -0400 Subject: [PATCH 39/73] 1st Deriv serial pass all tests, GPU in progress --- BSplineKokkos.h | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 5addf48..65cde29 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -196,7 +196,7 @@ class BSplineKokkos { auto order_mv = Kokkos::create_mirror_view(order); Kokkos::deep_copy(order_mv, order); int lKnot = order_mv(splineo)-1; - + //std::cout << lKnot << std::endl; //Find the range that contains this spline //Need to make sure it is within the range of this spline @@ -211,7 +211,7 @@ class BSplineKokkos { //Search within this range while (mv_knots(lKnot+1) < x) { - lKnot+=2; + lKnot++; leftPtX+=2; //Increment xpts leftPtY+=2; //Increment ypts } @@ -227,57 +227,57 @@ class BSplineKokkos { auto mv_ptsX = Kokkos::create_mirror_view(ptsX); Kokkos::View ptsY("ptsY", order_t); auto mv_ptsY = Kokkos::create_mirror_view(ptsY); - for (int i = leftPtX; i < leftPtX+order_t-1; i+=2) { - //std::cout << i << "|" << mv_ctrlPts_1stD(i) << std::endl; + + for (int i = leftPtX; i < leftPtX+2*(order_t); i+=2) { mv_ptsX(idx) = mv_ctrlPts_1stD(i); mv_ptsY(idx) = mv_ctrlPts_1stD(i+1); idx++; } - /*for (int i = 0; i < mv_ptsX.extent(0); i++) { - std::cout << mv_ptsX(i) << std::endl; - } - std::cout << "|" << std::endl;*/ - //We only need 1 copy of the local knots idx = 0; Kokkos::View localKnots("local knots", 2*order_t-2); auto mv_localKnots = Kokkos::create_mirror_view(localKnots); - for (int i = lKnot-order_t+2; i < lKnot+order_t+1; i++) { + + + for (int i = lKnot-order_t+2; i < lKnot+order_t; i++) { mv_localKnots(idx) = mv_knots(i); + idx++; } - //std::cout << "Local knots collection complete" << std::endl; //Copy allocated value back to device Kokkos::deep_copy(localKnots, mv_localKnots); Kokkos::deep_copy(ptsX, mv_ptsX); Kokkos::deep_copy(ptsY, mv_ptsY); - Kokkos::parallel_for("1st derivative loop", order_t, KOKKOS_LAMBDA(int r) { - for (int i = order_t-1; i >= r+1; i--) { + Kokkos::parallel_for("1st derivative loop", Kokkos::RangePolicy<>(1, order_t+1), KOKKOS_LAMBDA(int r) { + for (int i = order_t-1; i >= r; i--) { double aLeft = localKnots(i-1); - double aRight = localKnots(i+order_t-(r+1)-1); + double aRight = localKnots(i+order_t-(r)-1); double alpha; if (aLeft == aRight) { alpha = 0.; } else { alpha = (x-aLeft)/(aRight-aLeft); - } - ptsX(i) = (1. - alpha) * ptsX(i-1)+alpha*ptsX(i); - ptsY(i) = (1. - alpha) * ptsY(i-1)+alpha*ptsY(i); + } + ptsX(i) = ((1. - alpha) * ptsX(i-1))+(alpha*ptsX(i)); + ptsY(i) = ((1. - alpha) * ptsY(i-1))+(alpha*ptsY(i)); } - }); + }); + + Kokkos::fence(); //std::cout << "Before deep copy of pts" << std::endl; Kokkos::deep_copy(mv_ptsX, ptsX); Kokkos::deep_copy(mv_ptsY, ptsY); //std::cout << "After deep copy of pts" << std::endl; - /*for (int i = 0; i < mv_ptsX.extent(0); i++) { - std::cout << mv_ptsX(i) << std::endl; - }*/ + for (int i = 0; i < mv_ptsX.extent(0); i++) { + std::cout << "Result idx: " << i << ":" << mv_ptsX(i) << "|"<< mv_ptsY(i) < result; result.push_back(mv_ptsX(order_t-1)); - result.push_back(mv_ptsY(order_t-1)); + result.push_back(mv_ptsY(order_t-1)); return result; } @@ -344,7 +344,7 @@ class BSplineKokkos { Kokkos::deep_copy(ptsX, mv_ptsX); Kokkos::deep_copy(ptsY, mv_ptsY); - Kokkos::parallel_for ("2nd derivative loop", order_t, KOKKOS_LAMBDA(int r){ + /*Kokkos::parallel_for ("2nd derivative loop", order_t, KOKKOS_LAMBDA(int r){ for (int i = order_t-1; i >= r+1; i--) { double aLeft = localKnots(i-1); double aRight = localKnots(i+order_t-(r+1)-1); @@ -359,7 +359,8 @@ class BSplineKokkos { ptsX(i) = (1. - alpha) * ptsX(i-1)+alpha*ptsX(i); } - }); + });*/ + Kokkos::deep_copy(mv_ptsX, ptsX); return mv_ptsX(order_t-1); From 3a73fe02a76c29b4b04a3cda55792aad91c4c79b Mon Sep 17 00:00:00 2001 From: Hsieh Date: Wed, 8 Apr 2026 10:06:51 -0400 Subject: [PATCH 40/73] Made kokkos 1st deriv test concise & automatable --- testKokkos1stDerivative.cpp | 198 +++++------------------------------- 1 file changed, 23 insertions(+), 175 deletions(-) diff --git a/testKokkos1stDerivative.cpp b/testKokkos1stDerivative.cpp index 457908f..8395608 100644 --- a/testKokkos1stDerivative.cpp +++ b/testKokkos1stDerivative.cpp @@ -59,9 +59,10 @@ void printVector(const std::string& name, std::vector& vector) { } } -double epsilon = 0.005; +double EPSILON = 0.005; int main(int argc, char* argv[]) { + int retVal = 0; Kokkos::initialize(argc, argv); { @@ -105,182 +106,29 @@ int main(int argc, char* argv[]) { BSplineKokkos kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); //printSpline(kokkosBSP); + std::vector evalAt = {0, 0.2, 0.41, 0.5, 0.66, 0.73, 0.75, 0.89, 0.94, 1}; - - /*INITALIZATION COMPLETE, TEST STARTS BELOW*/ - //TEST 1 HERE - std::cout << "TEST 1, EVAL AT 0" << std::endl; - double derivX = serialBSP.x.evalFirstDeriv(0); - double derivY = serialBSP.y.evalFirstDeriv(0); - std::cout << "SERIAL: 1st derivative, input x = 0: " << derivX << ", " << derivY << std::endl; - - std::vector kokkos1stDeriv = kokkosBSP.eval1stDeriv(0, 0); - double kokkosDerivX = kokkos1stDeriv[0]; - double kokkosDerivY = kokkos1stDeriv[1]; - - double derivXDiff = derivX - kokkosDerivX; - double derivYDiff = derivY - kokkosDerivY; - std::cout << "KOKKOS: 1st derivative, input x = 0: " << kokkosDerivX <<", " << kokkosDerivY << std::endl; - - std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; - - - //TEST 2 HERE - std::cout << "TEST 2, EVAL AT 0.2" << std::endl; - derivX = serialBSP.x.evalFirstDeriv(0.2); - derivY = serialBSP.y.evalFirstDeriv(0.2); - std::cout << "SERIAL: 1st derivative, input x = 0.2: " << derivX << ", " << derivY << std::endl; - kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.2, 0); - kokkosDerivX = kokkos1stDeriv[0]; - kokkosDerivY = kokkos1stDeriv[1]; - - derivXDiff = derivX - kokkosDerivX; - derivYDiff = derivY - kokkosDerivY; - - std::cout << "KOKKOS: 1st derivative, input x = 0.2: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; - - std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; - - - //TEST 3 - std::cout << "TEST 3: EVAL AT 0.41" << std::endl; - derivX = serialBSP.x.evalFirstDeriv(0.41); - derivY = serialBSP.y.evalFirstDeriv(0.41); - std::cout << "SERIAL: 1st derivative, input x = 0.41: " << derivX << ", " << derivY << std::endl; - - kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.41, 0); - kokkosDerivX = kokkos1stDeriv[0]; - kokkosDerivY = kokkos1stDeriv[1]; - - derivXDiff = derivX - kokkosDerivX; - derivYDiff = derivY - kokkosDerivY; - - std::cout << "KOKKOS: 1st derivative, input x = 0.41: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; - - std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; - - - //TEST 4 - std::cout << "TEST 4: EVAL AT 0.5" << std::endl; - derivX = serialBSP.x.evalFirstDeriv(0.5); - derivY = serialBSP.y.evalFirstDeriv(0.5); - std::cout << "SERIAL: 1st derivative, input x = 0.5: " << derivX << ", " << derivY << std::endl; - - kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.5, 0); - kokkosDerivX = kokkos1stDeriv[0]; - kokkosDerivY = kokkos1stDeriv[1]; - - derivXDiff = derivX - kokkosDerivX; - derivYDiff = derivY - kokkosDerivY; - - std::cout << "KOKKOS: 1st derivative, input x = 0.5: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; - - std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; - - //TEST 5 - std::cout << "TEST 5: EVAL AT 0.66" << std::endl; - derivX = serialBSP.x.evalFirstDeriv(0.66); - derivY = serialBSP.y.evalFirstDeriv(0.66); - std::cout << "SERIAL: 1st derivative, input x = 0.66: " << derivX << ", " << derivY << std::endl; - - kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.66, 0); - kokkosDerivX = kokkos1stDeriv[0]; - kokkosDerivY = kokkos1stDeriv[1]; - - derivXDiff = derivX - kokkosDerivX; - derivYDiff = derivY - kokkosDerivY; - - std::cout << "KOKKOS: 1st derivative, input x = 0.66: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; - - std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; - - - //TEST 6 - std::cout << "Test 6: EVAL AT 0.73" << std::endl; - derivX = serialBSP.x.evalFirstDeriv(0.73); - derivY = serialBSP.y.evalFirstDeriv(0.73); - std::cout << "SERIAL: 1st derivative, input x = 0.73: " << derivX << ", " << derivY << std::endl; - kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.73, 0); - kokkosDerivX = kokkos1stDeriv[0]; - kokkosDerivY = kokkos1stDeriv[1]; - - derivXDiff = derivX - kokkosDerivX; - derivYDiff = derivY - kokkosDerivY; - - std::cout << "KOKKOS: 1st derivative, input x = 0.73: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; - - std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; - - - //TEST 7 - std::cout << "TEST 7: EVAL AT 0.75" << std::endl; - derivX = serialBSP.x.evalFirstDeriv(0.75); - derivY = serialBSP.y.evalFirstDeriv(0.75); - std::cout << "SERIAL: 1st derivative, input x = 0.75: " << derivX << ", " << derivY << std::endl; - kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.75, 0); - kokkosDerivX = kokkos1stDeriv[0]; - kokkosDerivY = kokkos1stDeriv[1]; - - derivXDiff = derivX - kokkosDerivX; - derivYDiff = derivY - kokkosDerivY; - - std::cout << "KOKKOS: 1st derivative, input x = 0.75: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; - - std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; - - - //TEST 8 - std::cout << "TEST 8: EVAL AT 0.89" << std::endl; - derivX = serialBSP.x.evalFirstDeriv(0.89); - derivY = serialBSP.y.evalFirstDeriv(0.89); - std::cout << "SERIAL: 1st derivative, input x = 0.89: " << derivX << ", " << derivY << std::endl; - - kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.89, 0); - kokkosDerivX = kokkos1stDeriv[0]; - kokkosDerivY = kokkos1stDeriv[1]; - - derivXDiff = derivX - kokkosDerivX; - derivYDiff = derivY - kokkosDerivY; - - std::cout << "KOKKOS: 1st derivative, input x = 0.89: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; - - std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; - - - //TEST 9 - std::cout << "TEST 9: EVAL AT 0.94" << std::endl; - derivX = serialBSP.x.evalFirstDeriv(0.94); - derivY = serialBSP.y.evalFirstDeriv(0.94); - std::cout << "SERIAL: 1st derivative, input x = 0.94: " << derivX << ", " << derivY << std::endl; - kokkos1stDeriv = kokkosBSP.eval1stDeriv(0.94, 0); - kokkosDerivX = kokkos1stDeriv[0]; - kokkosDerivY = kokkos1stDeriv[1]; - - derivXDiff = derivX - kokkosDerivX; - derivYDiff = derivY - kokkosDerivY; - - std::cout << "KOKKOS: 1st derivative, input x = 0.94: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; - - std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; - - - //TEST 10 - std::cout << "TEST 10: EVAL AT 1" << std::endl; - derivX = serialBSP.x.evalFirstDeriv(1); - derivY = serialBSP.y.evalFirstDeriv(1); - std::cout << "SERIAL: 1st derivative, input x = 1: " << derivX << ", " << derivY << std::endl; - - kokkos1stDeriv = kokkosBSP.eval1stDeriv(1, 0); - kokkosDerivX = kokkos1stDeriv[0]; - kokkosDerivY = kokkos1stDeriv[1]; - - derivXDiff = derivX - kokkosDerivX; - derivYDiff = derivY - kokkosDerivY; - - std::cout << "KOKKOS: 1st derivative, input x = 1: " << kokkosDerivX << ", " << kokkosDerivY << std::endl; - - std::cout << "Serial and Kokkos Difference: " << derivXDiff << ", " << derivYDiff << std::endl; + for (int i = 0; i < 10; i++) { + double derivX = serialBSP.x.evalFirstDeriv(evalAt[i]); + double derivY = serialBSP.y.evalFirstDeriv(evalAt[i]); + std::vector kokkos1stDeriv = kokkosBSP.eval1stDeriv(evalAt[i], 0); + double kokkosDerivX = kokkos1stDeriv[0]; + double kokkosDerivY = kokkos1stDeriv[1]; + + double derivXDiff = std::fabs(derivX - kokkosDerivX); + double derivYDiff = std::fabs(derivY - kokkosDerivY); + + if (derivXDiff > EPSILON || derivYDiff > EPSILON) { + std::cout << "Test " << i+1 << " failed, eval at: " << evalAt[i] << std::endl; + std::cout << "EPSILON = " << EPSILON << std::endl; + std::cout << "SERIAL/KOKKOS DIFFERENCE: xcoor = " << derivXDiff << " ycoor = " << derivYDiff << std::endl; + std::cout << "SERIAL 1st Derivative: x = " << derivX << " y = " << derivY << std::endl; + std::cout << "KOKKOS 1st Derivative: x = " << kokkosDerivX << " y = " << kokkosDerivY << std::endl; + retVal = 1; + } + } } Kokkos::finalize(); + return retVal; } From d64a89e362189491e6d3814b3dc3a1acff09489b Mon Sep 17 00:00:00 2001 From: Hsieh Date: Wed, 8 Apr 2026 10:09:45 -0400 Subject: [PATCH 41/73] Fixed difference calculation error --- testKokkos1stDerivative.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testKokkos1stDerivative.cpp b/testKokkos1stDerivative.cpp index 8395608..737a723 100644 --- a/testKokkos1stDerivative.cpp +++ b/testKokkos1stDerivative.cpp @@ -115,8 +115,8 @@ int main(int argc, char* argv[]) { double kokkosDerivX = kokkos1stDeriv[0]; double kokkosDerivY = kokkos1stDeriv[1]; - double derivXDiff = std::fabs(derivX - kokkosDerivX); - double derivYDiff = std::fabs(derivY - kokkosDerivY); + double derivXDiff = std::fabs(derivX) - std::fabs(kokkosDerivX); + double derivYDiff = std::fabs(derivY) - std::fabs(kokkosDerivY); if (derivXDiff > EPSILON || derivYDiff > EPSILON) { std::cout << "Test " << i+1 << " failed, eval at: " << evalAt[i] << std::endl; From d42426962de73fc0b0ae53cc1414ae41e7b86398 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Wed, 8 Apr 2026 10:10:32 -0400 Subject: [PATCH 42/73] Known Error at parallel_for in 1stDeriv evaluation --- BSplineKokkos.h | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index 65cde29..f06d7e1 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -19,18 +19,18 @@ class BSplineKokkos { //In the original implementation, we had the x and y components separated and was storing redundant knots information //The implementation now change to interleave the x and y coordinates //We store just 1 set of knots rather than 2 - std::cout << "Start BSpline Construction" << std::endl; + //std::cout << "Start BSpline Construction" << std::endl; Kokkos::View orderV("Orders", 1); auto host_orderV = Kokkos::create_mirror_view(orderV); host_orderV(0) = order_p; order = orderV; Kokkos::deep_copy(order, host_orderV); - std::cout << "Order inputted" << std::endl; + //std::cout << "Order inputted" << std::endl; //Initialize control points and their offset Kokkos::View ctrlPtsV("CtrlPoints", 2*ctrlPts_x.size()); //Create the mirror on host so we can access the vector values auto host_ctrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); - std::cout << "ctrlPts size: " << host_ctrlPtsV.extent(0) << std::endl; + //std::cout << "ctrlPts size: " << host_ctrlPtsV.extent(0) << std::endl; for (int i = 0; i < ctrlPts_x.size(); i++) { host_ctrlPtsV(2*i) = ctrlPts_x[i]; @@ -65,10 +65,10 @@ class BSplineKokkos { knotsOffset = knotsOffsetV; Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); - std::cout << "All good, before derivative coe" << std::endl; + //std::cout << "All good, before derivative coe" << std::endl; //Derivative coefficients calculateDerivCoeff(); - std::cout << "single spline initialization ok" << std::endl; + //std::cout << "single spline initialization ok" << std::endl; } @@ -250,10 +250,13 @@ class BSplineKokkos { Kokkos::deep_copy(ptsX, mv_ptsX); Kokkos::deep_copy(ptsY, mv_ptsY); + + //TO DO: Debug the below for kokkos parallel for loop + //We have found the error restricted to this for loop Kokkos::parallel_for("1st derivative loop", Kokkos::RangePolicy<>(1, order_t+1), KOKKOS_LAMBDA(int r) { for (int i = order_t-1; i >= r; i--) { double aLeft = localKnots(i-1); - double aRight = localKnots(i+order_t-(r)-1); + double aRight = localKnots(((i+order_t)-r)-1); double alpha; if (aLeft == aRight) { alpha = 0.; @@ -271,9 +274,6 @@ class BSplineKokkos { Kokkos::deep_copy(mv_ptsX, ptsX); Kokkos::deep_copy(mv_ptsY, ptsY); //std::cout << "After deep copy of pts" << std::endl; - for (int i = 0; i < mv_ptsX.extent(0); i++) { - std::cout << "Result idx: " << i << ":" << mv_ptsX(i) << "|"<< mv_ptsY(i) < result; result.push_back(mv_ptsX(order_t-1)); @@ -344,7 +344,7 @@ class BSplineKokkos { Kokkos::deep_copy(ptsX, mv_ptsX); Kokkos::deep_copy(ptsY, mv_ptsY); - /*Kokkos::parallel_for ("2nd derivative loop", order_t, KOKKOS_LAMBDA(int r){ + Kokkos::parallel_for ("2nd derivative loop", order_t, KOKKOS_LAMBDA(int r){ for (int i = order_t-1; i >= r+1; i--) { double aLeft = localKnots(i-1); double aRight = localKnots(i+order_t-(r+1)-1); @@ -359,7 +359,7 @@ class BSplineKokkos { ptsX(i) = (1. - alpha) * ptsX(i-1)+alpha*ptsX(i); } - });*/ + }); Kokkos::deep_copy(mv_ptsX, ptsX); return mv_ptsX(order_t-1); @@ -409,7 +409,7 @@ class BSplineKokkos { //Calculate first order derivative //Allocate the space - std::cout << "calculating derivative coeff" << std::endl; + //std::cout << "calculating derivative coeff" << std::endl; Kokkos::View ctrlPts_1stDV("ctrlPts1Derivative", ctrlPts.extent(0)-(2*cPOffset.extent(0))); Kokkos::View cP1stDOffsetV("ctrlPts1DerivativeOffset", cPOffset.extent(0)); Kokkos::View cP2ndDOffsetV("ctrlPts2DerivativeOffset", cPOffset.extent(0)); @@ -418,7 +418,7 @@ class BSplineKokkos { auto host_cP1stDOffsetV = Kokkos::create_mirror_view(cP1stDOffsetV); - std::cout << "offset views and 1stctrlPts views construct" << std::endl; + //std::cout << "offset views and 1stctrlPts views construct" << std::endl; //Adjust the offset to include be 1 & 2 less than the ctrlPtsOffset @@ -438,7 +438,7 @@ class BSplineKokkos { host_cP2ndDOffsetV(0) = host_cPOffset(0)-4; } - std::cout << "offset view populated" << std::endl; + //std::cout << "offset view populated" << std::endl; //We need to partition the x and y while we calculate the coefficient int idx = 0; @@ -456,7 +456,7 @@ class BSplineKokkos { Kokkos::deep_copy(host_order, order); Kokkos::deep_copy(host_ctrlPts, ctrlPts); - std::cout << "Copied ctrlPts, knots, order" << std::endl; + //std::cout << "Copied ctrlPts, knots, order" << std::endl; //We need to keep track of the indicies of the splines //We ignore the first ctrl point, starting at idx = 2 for (int i = 2; i < host_ctrlPts.extent(0); i++) { @@ -475,7 +475,7 @@ class BSplineKokkos { host_ctrlPts_1stDV(i-2) = (host_ctrlPts(i)-host_ctrlPts(i-2))*deltaHold; } - std::cout << "1stD coeff populated" << std::endl; + //std::cout << "1stD coeff populated" << std::endl; Kokkos::View ctrlPts_2ndDV("ctrlPts2Derivative", ctrlPts.extent(0)-(2*cPOffset.extent(0))-2); auto host_ctrlPts_2ndDV = Kokkos::create_mirror_view(ctrlPts_2ndDV); From 793c6c07919e9b1165dd7485927a8497767143b9 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Sat, 11 Apr 2026 14:29:33 -0400 Subject: [PATCH 43/73] Fixed formatting and argumnet check --- testKokkos1stDerivative.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/testKokkos1stDerivative.cpp b/testKokkos1stDerivative.cpp index 737a723..b361d57 100644 --- a/testKokkos1stDerivative.cpp +++ b/testKokkos1stDerivative.cpp @@ -59,10 +59,18 @@ void printVector(const std::string& name, std::vector& vector) { } } -double EPSILON = 0.005; +double EPSILON = 1e-12; int main(int argc, char* argv[]) { int retVal = 0; + + if (argc != 3) { + //Check for the arguments needed + std::cerr<< "Input arguments: " << std::endl; + std::cerr << "input csv need these columns: "; + std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; + return 1; + } Kokkos::initialize(argc, argv); { @@ -78,10 +86,6 @@ int main(int argc, char* argv[]) { using ExecutionSpace = MemSpace::execution_space; - - if (argc != 3) { //Check for the arguments needed std::cerr<<"Input arguments: " << std::endl; std::cerr << "input csv need these columns: "; - std::cerr << "x,y,z,isOnCurve,angle,isMdlVtx" << std::endl; - return 1; } std::string inputCSV = argv[1]; int extensionPos = inputCSV.rfind("."); int slashPos = inputCSV.rfind("/"); @@ -93,7 +97,7 @@ int main(int argc, char* argv[]) { SplineInterp::BSpline2d serialBSP; if (curve.x.size() == 2) { serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); - } else { + } else { serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); } From b9db307c7c11d495d669201f6ed944cdcc07be00 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Wed, 15 Apr 2026 15:24:00 -0400 Subject: [PATCH 44/73] Changed 1st deriv to device function --- BSplineKokkos.h | 118 ++++++++++++++++++------------------------------ 1 file changed, 44 insertions(+), 74 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index f06d7e1..cddd676 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -191,94 +191,64 @@ class BSplineKokkos { } - std::vector eval1stDeriv(double x, int splineo) const { - //Find the order based on the spline number given - auto order_mv = Kokkos::create_mirror_view(order); - Kokkos::deep_copy(order_mv, order); - int lKnot = order_mv(splineo)-1; + //We perform De Boor recursion here + KOKKOS_FUNCTION void evalDeBoor (double x, int splineo, int lKnot, Kokkos::View result, const Kokkos::View order, const Kokkos::View knots, const Kokkos::View ctrlPts_1stD) const { + + int order_t = lKnot; - //std::cout << lKnot << std::endl; - //Find the range that contains this spline - //Need to make sure it is within the range of this spline - - int leftPtX = 0; //Even indicies are x coordinates - int leftPtY = 1; //Odd indicies are y coordinates - - //Find the boundary to the current spline control points - - auto mv_knots = Kokkos::create_mirror_view(knots); - Kokkos::deep_copy(mv_knots, knots); + int leftPtX = 0; + int leftPtY = 1; - //Search within this range - while (mv_knots(lKnot+1) < x) { - lKnot++; - leftPtX+=2; //Increment xpts - leftPtY+=2; //Increment ypts + while (x > knots(lKnot+1)) { + lKnot++; + leftPtX+=2; + leftPtY+=2; } - int order_t = order_mv(splineo)-1; + double ptsX[3]; + double ptsY[3]; - //Copy our previously calculated coefficient - auto mv_ctrlPts_1stD = Kokkos::create_mirror_view(ctrlPts_1stD); - Kokkos::deep_copy(mv_ctrlPts_1stD, ctrlPts_1stD); - int idx = 0; - Kokkos::View ptsX("ptsX", order_t); - auto mv_ptsX = Kokkos::create_mirror_view(ptsX); - Kokkos::View ptsY("ptsY", order_t); - auto mv_ptsY = Kokkos::create_mirror_view(ptsY); - for (int i = leftPtX; i < leftPtX+2*(order_t); i+=2) { - mv_ptsX(idx) = mv_ctrlPts_1stD(i); - mv_ptsY(idx) = mv_ctrlPts_1stD(i+1); - idx++; + ptsX[idx] = ctrlPts_1stD(i); + ptsY[idx] = ctrlPts_1stD(i+1); + idx++; } - //We only need 1 copy of the local knots - idx = 0; - Kokkos::View localKnots("local knots", 2*order_t-2); - auto mv_localKnots = Kokkos::create_mirror_view(localKnots); - + auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order_t+2, lKnot+order_t)); - for (int i = lKnot-order_t+2; i < lKnot+order_t; i++) { - mv_localKnots(idx) = mv_knots(i); - idx++; + //I am still working on the offset for the knots + for (int r = 1; r <= order_t; r++) { + for (int i = order_t-1; i >= r; i--) { + double alpha; + if (localKnots(i-1) == localKnots(i+order_t-r-1)) { + alpha = 0.; + } + else { + alpha = (x - localKnots(i-1))/(knots(i+order_t-r-1) - knots(i-1)); + } + ptsX[i] = (1. - alpha) * ptsX[i-1] + alpha * ptsX[i]; + ptsY[i] = (1. - alpha) * ptsY[i-1] + alpha * ptsY[i]; + } } - //Copy allocated value back to device - Kokkos::deep_copy(localKnots, mv_localKnots); - Kokkos::deep_copy(ptsX, mv_ptsX); - Kokkos::deep_copy(ptsY, mv_ptsY); - - - //TO DO: Debug the below for kokkos parallel for loop - //We have found the error restricted to this for loop - Kokkos::parallel_for("1st derivative loop", Kokkos::RangePolicy<>(1, order_t+1), KOKKOS_LAMBDA(int r) { - for (int i = order_t-1; i >= r; i--) { - double aLeft = localKnots(i-1); - double aRight = localKnots(((i+order_t)-r)-1); - double alpha; - if (aLeft == aRight) { - alpha = 0.; - } - else { - alpha = (x-aLeft)/(aRight-aLeft); - } - ptsX(i) = ((1. - alpha) * ptsX(i-1))+(alpha*ptsX(i)); - ptsY(i) = ((1. - alpha) * ptsY(i-1))+(alpha*ptsY(i)); - } - }); + result(0) = ptsX[order_t-1]; + result(1) = ptsY[order_t-1]; - Kokkos::fence(); - //std::cout << "Before deep copy of pts" << std::endl; - Kokkos::deep_copy(mv_ptsX, ptsX); - Kokkos::deep_copy(mv_ptsY, ptsY); - //std::cout << "After deep copy of pts" << std::endl; + } - std::vector result; - result.push_back(mv_ptsX(order_t-1)); - result.push_back(mv_ptsY(order_t-1)); - return result; + std::vector eval1stDeriv(std::vector xVals, int splineo) const { + + int lKnot; + Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); + lKnot--; + Kokkos::View res("result", 2); + Kokkos::parallel_for("parallel call for evalDeBoors", xVals.size(), KOKKOS_CLASS_LAMBDA(int i) { + evalDeBoor(xVals[i], splineo, lKnot, res, order, knots, ctrlPts_1stD); + }); + auto mvRes = Kokkos::create_mirror_view(res); + Kokkos::deep_copy(mvRes, res); + return {mvRes(0), mvRes(1)}; } double eval2ndDeriv(double x, int splineo) const { From ff2e5f7395a4488f2dc59eb82a5ca1ce74c45128 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Wed, 15 Apr 2026 15:25:16 -0400 Subject: [PATCH 45/73] Change x to vector of x, eval ok for cpu & gpu --- testKokkos1stDerivative.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testKokkos1stDerivative.cpp b/testKokkos1stDerivative.cpp index b361d57..15fb8ba 100644 --- a/testKokkos1stDerivative.cpp +++ b/testKokkos1stDerivative.cpp @@ -115,7 +115,7 @@ int main(int argc, char* argv[]) { for (int i = 0; i < 10; i++) { double derivX = serialBSP.x.evalFirstDeriv(evalAt[i]); double derivY = serialBSP.y.evalFirstDeriv(evalAt[i]); - std::vector kokkos1stDeriv = kokkosBSP.eval1stDeriv(evalAt[i], 0); + std::vector kokkos1stDeriv = kokkosBSP.eval1stDeriv({evalAt[i]}, 0); double kokkosDerivX = kokkos1stDeriv[0]; double kokkosDerivY = kokkos1stDeriv[1]; From 93e722be2a39a363aa83e066884b918b9bd85a2e Mon Sep 17 00:00:00 2001 From: Hsieh Date: Wed, 15 Apr 2026 15:26:56 -0400 Subject: [PATCH 46/73] Update the input type for eval 1st derivative --- testSplineKokkosBase.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/testSplineKokkosBase.cpp b/testSplineKokkosBase.cpp index 9bc55e1..dd35ca8 100644 --- a/testSplineKokkosBase.cpp +++ b/testSplineKokkosBase.cpp @@ -74,7 +74,6 @@ int main(int argc, char* argv[]) { using ExecutionSpace = MemSpace::execution_space; //We will try to test with dummy data for BSplineKokkos creation std::vector dummyCtrlPtsX{2.14, 3.98, 1.56, 9.10, 11.87}; - std::vector dummyCtrlPtsY{7.928, 12.18, 9.17, 6.67, 12.78}; std::vector dummyKnotsX{5.99, 8.98, 17.71, 21.1, 2.154, 9.17, 6.32}; //std::vector dummyKnotsY{2.85, 1.16, 0.82, 1.89, 9.82, 12.0, 7.19}; @@ -184,13 +183,18 @@ int main(int argc, char* argv[]) { for (int i = 1; i < host_dView.extent(0); i+=2) { std::cout <<"Point: " << host_dView(i-1) << ", " << host_dView(i) << std::endl; } - std::cout << "1st derivative, input x = 0: " << kokkosBSP.eval1stDeriv(0, 0) << std::endl; + std::cout << "1st derivative, input x = 0: " << kokkosBSP.eval1stDeriv({0}, 0)[0] << std::endl; - std::cout << "1st derivative, input x = 1: " << kokkosBSP.eval1stDeriv(1, 0) << std::endl; + std::cout << "1st derivative, input x = 1: " << kokkosBSP.eval1stDeriv({1}, 0)[0] << std::endl; std::cout << "----Serial 2nd derivative----" << std::endl; - std::cout << "2nd derivative, input x = 0: " << serialBSP.x.evalSecondDeriv(0) << ", " << serialBSP.y.evalSecondDeriv(0) << std::endl; - std::cout << "2nd derivative, input x = 1: " << serialBSP.x.evalSecondDeriv(1) << ", " << serialBSP.y.evalSecondDeriv(1) << std::endl; + double x2ndD = serialBSP.x.evalSecondDeriv(0); + double y2ndD = serialBSP.y.evalSecondDeriv(0); + std::cout << "2nd derivative, input x = 0: " << x2ndD << ", " << y2ndD << std::endl; + + x2ndD = serialBSP.x.evalSecondDeriv(1); + y2ndD = serialBSP.y.evalSecondDeriv(1); + std::cout << "2nd derivative, input x = 1: " << x2ndD << ", " << y2ndD << std::endl; std::cout << "----Kokkos 2nd derivative----" << std::endl; //Get and copy the control points here so we could print them From b770910de9d78c9521ffe87215602455eddbd1e8 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Sun, 19 Apr 2026 20:28:37 -0400 Subject: [PATCH 47/73] Added 1spline constructor and accessors --- BSplineKokkos2D.h | 94 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 BSplineKokkos2D.h diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h new file mode 100644 index 0000000..1a5e5cf --- /dev/null +++ b/BSplineKokkos2D.h @@ -0,0 +1,94 @@ +#ifndef BSPLINEKOKKOS_H +#define BSPLINEKOKKOS_H + +#include +#include +#include +#include + +template + +class BSPlineKokkos2DView { +public: + using MemSpace = typename ExecutionSpace::memory_space; + + BSplineKokkos2DView(int order_p, std::vector& ctrlPts_x, std::vector& ctrlPts_y, std::vector& knotsI) { + Kokkos::View orderV("Orders", 1); + auto host_orderV = Kokkos::create_mirror_view(orderV); + host_orderV(0) = order_p; + order = orderV; + Kokkos::deep_copy(order, host_orderV); + + Kokkos::View ctrlPtsV("ctrlPts", ctrlPts.size()); + auto host_ctrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); + for (int i = 0; i < ctrlPts_x.size(); i++) { + host_ctrlPtsV(i, 0) = ctrlPts_x(i); + host_ctrlPtsV(i, 1) = ctrlPts_y(i); + } + ctrlPts = ctrlPtsV; + Kokkos::deep_copy(ctrlPts, host_ctrlPtsV); + + Kokkos::View cpOffsetV("cpOffset", 1); + auto host_cpOffsetV = Kokkos::create_mirror_view(cpOffsetV); + host_cpOffsetV(0, 0) = ctrlPts_x.size(); + host_cpOffsetV(0, 1) = ctrlPts_x.size(); + + cpOffset = cpOffsetV; + Kokkos::deep_copy(cpOffset, host_cpOffsetV); + + Kokkos::View knotsV("knots", knotsI.size()); + auto host_knotsV = Kokkos::create_mirror_view(knotsV); + for (int i = 0; i < knotsI.size(); i++) { + host_knotsV(i) = knotsI[i]; + } + knots = knotsV; + Kokkos::deep_copy(knots, host_knotsV(i)); + + Kokkos::View knotsOffsetV("knotsOffset", 1); + auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); + host_knotsOffsetV(0) = knotsI.size(); + knotsOffset = knotsOffsetV; + Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); + + //Later we need to address the coef calculation situation + } + + BSplineKokkos2DView(std::vector& multiSplines) { + //Loop over all the splines to know how much space to allocate + int orderSize = 0; + int ctrlPtsSize = 0; + int cpOffsetSize = 0; + int knotSize = 0; + int knotsOffsetSize = 0; + + for (int i = 0; i < multiSplines.size(); i++) { + orderSize += multiSplines[i]; + } + } + + //Accessors + Kokkos::View getOrder() const {return order;} + Kokkos::View getCtrlPts() const {return ctrlPts;} + Kokkos::View getCPOffset() const {return cPOffset;} + Kokkos::View getKnots() const {return knots;} + Kokkos::View getKnotsOffset() const {return knotsOffset;} + Kokkos::View getCP1stD() const {return ctrlPts1stD;} + Kokkos::View getCP1stDOffset() const {return cp1stDOffset;} + Kokkos::View getCP2ndD() const {return ctrlPts2ndD;} + Kokkos::View getCP2ndDOffset() const {return cp2ndDOffset;} + + +private: + Kokkos::View order; + Kokkos::View ctrlPts; + kokkos::View cpOffset; + Kokkos::View knots; + Kokkos::View knotsOffset; + Kokkos::View ctrlPts1stD; + Kokkos::View ctrlPts2ndD; + Kokkos::View cp1stDOffset; + Kokkos::View cp2ndDOffset; + +}; + +#endif From 6730696e1a664156fa7a6634822d571bdf248ff9 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Sun, 19 Apr 2026 21:35:17 -0400 Subject: [PATCH 48/73] Added multispline constructor --- BSplineKokkos2D.h | 94 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 92 insertions(+), 2 deletions(-) diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h index 1a5e5cf..6afb19e 100644 --- a/BSplineKokkos2D.h +++ b/BSplineKokkos2D.h @@ -50,7 +50,7 @@ class BSPlineKokkos2DView { knotsOffset = knotsOffsetV; Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); - //Later we need to address the coef calculation situation + //TO DO: Implement 1st&2nd Coef function } BSplineKokkos2DView(std::vector& multiSplines) { @@ -62,8 +62,98 @@ class BSPlineKokkos2DView { int knotsOffsetSize = 0; for (int i = 0; i < multiSplines.size(); i++) { - orderSize += multiSplines[i]; + orderSize += multiSplines[i].getOrder().extent(0); + ctrlPtsSize += multiSplines[i].getCtrlPts().extent(0); + cpOffsetSize += multiSplines[i].getCPOffset().extent(0); + knotSize += multiSplines[i].getKnots().extent(0); + knotsOffsetSize += multiSpline[i].getKnotsOffset().extent(0); } + + //Populate the views + Kokkos::View orderV ("order", orderSize); + Kokkos::View ctrlPtsV("ctrlPts", ctrlPtsSize); + Kokkos::View cPOffsetV("ctrlPtsOffset", cPOffsetSize); + Kokkos::View knotsV("knots", knotSize); + Kokkos::View knotsOffsetV("knotsOffset", knotsOffsetSize); + + //Create the mirror view on host to move the data over + auto mvOrderV = Kokkos::create_mirror_view(orderV); + auto mvCtrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); + auto mvCPOffsetV = Kokkos::create_mirror_view(cPOffsetV); + auto mvKnotsV = Kokkos::create_mirror_view(knotsV); + auto mvKnotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); + //Copy the data over + int oidx = 0; + int cPidx = 0; + int cOidx = 0; + int kidx = 0; + int kOidx = 0; + for (int i = 0; i < multiSplines.size(); i++) { + //Populate orders + Kokkos::View intView = multiSplines[i].getOrder(); + auto mvIntView = Kokkos::create_mirror_view(intView); + Kokkos::deep_copy(mvIntView, intView); + for (int j = 0; j < intView.extent(0); j++) { + mvOrderV(oidx+j) = mvIntView(j); + } + oidx += mvIntView.extent(0); + + //Populate ctrlPts + Kokkos::View double2DView = multiSplines[i].getCtrlPts(); + auto mvDouble2DView = Kokkos::create_mirror_view(double2DView); + Kokkos::deep_copy(mvDouble2DView, double2DView); + for (int j = 0; j < mvDouble2DView.extent(0); j++) { + mvCtrlPtsV(cPidx+j, 0) = mvDouble2DView(j, 0); + mvCtrlPtsV(cPidx+j, 1) = mvDouble2DView(j, 1); + } + cPidx += mvDouble2dView.extent(0); + + //Populate ctrlPtsOffset + intView = mutiSplines[i].getCPOffset(); + mvIntView = Kokkos::create_mirror_view(intView); + Kokkos::deep_copy(mvIntView, intView); + + for (int j = 0; j < intView.extent(0); j++) { + mvCPOffsetV(cOidx + j) = intView(j); + } + cOidx += intView.extent(0); + + //Populate knots + Kokkos::View doubleView = multiSplines[i].getKnots(); + auto mvDoubleView = Kokkos::create_mirror_view(doubleView); + Kokkos::deep_copy(mvDoubleView, doubleView); + + for (int j = 0; j < doubleView.extent(0); j++) { + mvKnotsV(kidx+j) = doubleView(j); + } + kidx += doubleView.extent(0); + + //Populate knots offset + intView = multiSpliens[i].getKnotsOffset(); + mvIntView = Kokkos::create_mirror_view(intView); + Kokkos::deep_copy(mvIntView, intView); + + for (int j = 0; j < intView.extent(0); j++) { + mvKnotsOffsetV(kOidx+j) = mvIntView(j); + } + kOidx += mvIntView.extent(0); + } + + //Copy the data on host to device + order = orderV; + ctrlPts = ctrlPtsV; + cPOffset = cPOffset; + knots = knotsV; + knotsOffset = knotsOffsetV; + + Kokkos::deep_copy(order, mvOrderV); + Kokkos::deep_copy(ctrlPts, mvCtrlPtsV); + Kokkos::deep_copy(cPOffset, mvCPOffsetV); + Kokkos::deep_copy(knots, mvKnotsV); + Kokkos::deep_copy(knotsOffset, mvKnotsOffsetV); + + //TO DO: Implement 1st&2nd Coef function + } //Accessors From 0d429d7778cfeaaca7c3e15cfff787fe8fef5966 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Sun, 19 Apr 2026 21:50:35 -0400 Subject: [PATCH 49/73] Coef calculation function in progress --- BSplineKokkos2D.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h index 6afb19e..37b9ed2 100644 --- a/BSplineKokkos2D.h +++ b/BSplineKokkos2D.h @@ -156,6 +156,16 @@ class BSPlineKokkos2DView { } + void calculateDerivCoeff() { + //Allocate the views we need + Kokkos::View ctrlPts1stDV("ctrlPts1stDeriv", ctrlPts.extent(0)-cpOffset.extent(0)); + Kokkos::View cP1stDOffsetV("cP1stDOffset", cpOffset.extent(0)); + Kokkos::View cP2ndDOffsetV("cP2ndDOffset", cpOffset.extent(0)); + //Start by calculating cP1stDeriv coeff calculation + + + } + //Accessors Kokkos::View getOrder() const {return order;} Kokkos::View getCtrlPts() const {return ctrlPts;} From e45dbba86b807a6304457ca08b7b63fd52ceaeae Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 21 Apr 2026 17:19:06 -0400 Subject: [PATCH 50/73] Not test yet 1st pass implementation for coef calc --- BSplineKokkos2D.h | 62 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h index 37b9ed2..0cb9e49 100644 --- a/BSplineKokkos2D.h +++ b/BSplineKokkos2D.h @@ -51,6 +51,8 @@ class BSPlineKokkos2DView { Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); //TO DO: Implement 1st&2nd Coef function + calculateDerivCoeff(); + } BSplineKokkos2DView(std::vector& multiSplines) { @@ -153,6 +155,7 @@ class BSPlineKokkos2DView { Kokkos::deep_copy(knotsOffset, mvKnotsOffsetV); //TO DO: Implement 1st&2nd Coef function + calculateDerivCoeff(); } @@ -161,9 +164,64 @@ class BSPlineKokkos2DView { Kokkos::View ctrlPts1stDV("ctrlPts1stDeriv", ctrlPts.extent(0)-cpOffset.extent(0)); Kokkos::View cP1stDOffsetV("cP1stDOffset", cpOffset.extent(0)); Kokkos::View cP2ndDOffsetV("cP2ndDOffset", cpOffset.extent(0)); - //Start by calculating cP1stDeriv coeff calculation - + //Set up the offset views + auto mvCP1stDOffsetV = Kokkos::create_mirror_view(cP1stDOffsetV); + auto mvCP2ndDOffsetV = Kokkos::create_mirror_view(cP2ndDOffsetV); + + auto mvCPOffset = Kokkos::create_mirror_view(cPOffset); + Kokkos::deep_copy(mvCPOffset, cPOffset); + if (mvCPOffset.extent(0) > 1) { + mvCP1stDOffsetV(i) = mvCPOffset(i)-1; + mvCP2ndDOffsetV(i) = mvCPOffset(i)-2; + } + + auto mvOrder = Kokkos::create_mirror_view(order); + auto mvKnots = Kokkos::create_mirror_view(knots); + auto mvCtrlPts = Kokkos::create_mirror_view(ctrlPts); + auto mvCtrlPts1stDV = Kokkos::create_mirror_view(ctrlPts1stDV); + Kokkos::deep_copy(mvOrder, order); + Kokkos::deep_copy(mvKnots, knots); + Kokkos::deep_copy(mvCtrlPts, ctrlPts); + + //Calculate 1st derivative coef + int offidx = 0; //Offset index + int oidx = 0; //Order index + for (int i = 1; i < cltrPts1stDV.extent(0); i++) { + //We need to check whether we are on the border for the next spline in our structure + if (i == mvCP1stDOffsetV(offidx)) { + oidx++; + offidx++; + continue; //Skip to the next + } + double delta = double(mvOrder(oidx-1)) / (mvKnots(i+mvOrder(oidx-1)) - mvKnots(i)); + mvCtrlPts1stDV(i, 0) = (mvCtrlPts(i, 0) - mvCtrlPts(i-1, 0))*delta; + mvCtrlPts1stDV(i, 1) = (mvCtrlPts(i, 1) - mvCtrlPts(i-1, 1))*delta; + } + + //Calculate 2nd derivative coef + auto mvCtrlPts2ndDV = Kokkos::create_mirror_view(ctrlPts2ndDV); + for (int i = 1; i < ctrlPts1stDV.extent(0); i++) { + if (i == mvCP2ndDOffsetV(offidx)) { + oidx++; + offidx++; + continue; + } + double delta = double(mvOrder-2) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i+1)); + mvCtrlPts2ndDV(i, 0) = (mvCtrlPts(i, 0) - mvCtrlPts(i-1, 0)) * delta; + mvCtrlPts2ndDV(i, 1) = (mvCtrlPts(i, 1) - mvCtrlPts(i-1, 1)) * delta; + } + + //Copy to device + Kokkos::deep_copy(cP1stDOffsetV, mvCP1stDOffsetV); + Kokkos::deep_copy(cP2ndDOffsetV, mvCP2ndDOffsetV); + Kokkos::deep_copy(ctrlPts1stDV, mvCtrlPts1stDV); + Kokkos::deep_copy(ctrlPts2ndDV, mvCtrlPts2ndDV); + + cp1stDOffset = cP1stDOffsetV; + cp2ndDOffset = cP2ndDOffsetV; + ctrlPts1stD = ctrlPts1stDV; + ctrlPts2ndD = ctrlPts2ndDV; } //Accessors From 1d7fd2184ccde9b83ca73d7035926a001a055556 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 21 Apr 2026 17:43:06 -0400 Subject: [PATCH 51/73] Added new test for 2D view rep of Kokkos Spline --- CMakeLists.txt | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c7f769..d77737b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,9 @@ target_link_libraries(modelGen2d PRIVATE splineInterp Omega_h::omega_h) add_library(splineKokkos BSplineKokkos.cpp) target_link_libraries(splineKokkos PRIVATE Kokkos::kokkos) +add_library(splineKokkos2D BSplineKokkos2D.cpp) +target_link_libraries(splineKokkos2D PRIVATE Kokkos::kokkos) + set(testDataDir ${CMAKE_CURRENT_SOURCE_DIR}/contour_test_data) if(USE_SIMMODSUITE) @@ -176,7 +179,7 @@ set_tests_properties(testDiscoverTopo_L11pts PROPERTIES #THE FOLLOWING IS FOR BSPLINE_KOKKOS TESTS, MAY HAVE A LOT OF ERROR add_executable(testSplineKokkosBase testSplineKokkosBase.cpp) -target_link_libraries(testSplineKokkosBase PRIVATE modelGen2d curveReader splineKokkos Kokkos::kokkos splineInterp) +target_link_libraries(testSplineKokkosBase PRIVATE splineInterp curveReader modelGen2d splineKokkos Kokkos::kokkos) add_test(NAME testBSplineKokkosSerialStraightEdge COMMAND ./testSplineKokkosBase ${testDataDir}/testCurveStrightLine.csv 9) add_test(NAME testBSplineKokkosSerial_edge_2pts @@ -184,7 +187,7 @@ add_test(NAME testBSplineKokkosSerial_edge_2pts #TEST FOR BSPLINEKOKKOS 1ST DERIVATIVE add_executable(testKokkos1stDerivative testKokkos1stDerivative.cpp) -target_link_libraries(testKokkos1stDerivative PRIVATE modelGen2d curveReader splineKokkos Kokkos::kokkos splineInterp) +target_link_libraries(testKokkos1stDerivative PRIVATE splineInterp curveReader modelGen2d splineKokkos Kokkos::kokkos) add_test(NAME testKokkos1stDerivativeStraightEdge COMMAND ./testKokkos1stDerivative contour_test_data/testCurveStrightLine.csv 9) @@ -192,5 +195,15 @@ add_test(NAME testKokkos1stDerivativeStraightEdge add_test(NAME testKokkos1stDerivativeEdge2Pts COMMAND ./testKokkos1stDerivative contour_test_data/testCurve2pts.csv 1) - - +add_test(NAME testKokkos1stDerivativeSingleEdge + COMMAND ./testKokkos1stDerivative ${testDataDir}/testCurveSplineFitting.csv 12.2685) + +#TEST FOR BSPLINEKOKKOS2D CONSTRUCTOR +add_executable(testSplineKokkos2DBase testSplineKokkos2DBase.cpp) +target_link_libraries(testSplineKokkos2DBase PRIVATE splineInterp curveReader modelGen2d splineKokkos2D Kokkos::kokkos) +add_test(NAME testSplineKokkos2DStraightEdge + COMMAND ./testSplineKokkos2DBase contour_test_data/testCurveStrightLine.csv 9) +add_test(NAME testSplineKokkos2D2Pts + COMMAND ./testSplineKokkos2DBase contour_test_data/testCurve2pts.csv 1) +add_test(NAME testSplineKokkos2DSingleEdge + COMMAND ./testSplineKokkos2DBase ${testDataDir}/testCurveSplineFitting.csv 12.2685) From e25c9ef8448a50af513f2ae116d510217a1f2497 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 21 Apr 2026 17:43:45 -0400 Subject: [PATCH 52/73] For adding the library in CMakeLists.txt --- BSplineKokkos2D.cpp | 1 + 1 file changed, 1 insertion(+) create mode 100644 BSplineKokkos2D.cpp diff --git a/BSplineKokkos2D.cpp b/BSplineKokkos2D.cpp new file mode 100644 index 0000000..d26ee24 --- /dev/null +++ b/BSplineKokkos2D.cpp @@ -0,0 +1 @@ +#include "BSplineKokkos2D.h" From e562b356bcc02d851dfbd604f36551fac53d5796 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 21 Apr 2026 18:43:35 -0400 Subject: [PATCH 53/73] Syntax err fix for 2d kokkos spline test and class --- BSplineKokkos2D.h | 68 ++++++++++++++++++++++---------------- testSplineKokkos2DBase.cpp | 64 +++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 29 deletions(-) create mode 100644 testSplineKokkos2DBase.cpp diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h index 0cb9e49..6838410 100644 --- a/BSplineKokkos2D.h +++ b/BSplineKokkos2D.h @@ -1,5 +1,6 @@ -#ifndef BSPLINEKOKKOS_H -#define BSPLINEKOKKOS_H +#ifndef BSPLINEKOKKOS2D_H + +#define BSPLINEKOKKOS2D_H #include #include @@ -8,30 +9,30 @@ template -class BSPlineKokkos2DView { +class BSplineKokkos2D { public: using MemSpace = typename ExecutionSpace::memory_space; - - BSplineKokkos2DView(int order_p, std::vector& ctrlPts_x, std::vector& ctrlPts_y, std::vector& knotsI) { - Kokkos::View orderV("Orders", 1); + + BSplineKokkos2D(int order_p, std::vector& ctrlPts_x, std::vector& ctrlPts_y, std::vector& knotsI) { + Kokkos::View orderV("Orders", 1); auto host_orderV = Kokkos::create_mirror_view(orderV); host_orderV(0) = order_p; order = orderV; Kokkos::deep_copy(order, host_orderV); - Kokkos::View ctrlPtsV("ctrlPts", ctrlPts.size()); + Kokkos::View ctrlPtsV("ctrlPts", ctrlPts_x.size()); auto host_ctrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); for (int i = 0; i < ctrlPts_x.size(); i++) { - host_ctrlPtsV(i, 0) = ctrlPts_x(i); - host_ctrlPtsV(i, 1) = ctrlPts_y(i); + host_ctrlPtsV(i, 0) = ctrlPts_x[i]; + host_ctrlPtsV(i, 1) = ctrlPts_y[i]; } ctrlPts = ctrlPtsV; Kokkos::deep_copy(ctrlPts, host_ctrlPtsV); - Kokkos::View cpOffsetV("cpOffset", 1); + Kokkos::View cpOffsetV("cpOffset", 1); auto host_cpOffsetV = Kokkos::create_mirror_view(cpOffsetV); - host_cpOffsetV(0, 0) = ctrlPts_x.size(); - host_cpOffsetV(0, 1) = ctrlPts_x.size(); + host_cpOffsetV(0) = ctrlPts_x.size(); + host_cpOffsetV(0) = ctrlPts_x.size(); cpOffset = cpOffsetV; Kokkos::deep_copy(cpOffset, host_cpOffsetV); @@ -42,7 +43,7 @@ class BSPlineKokkos2DView { host_knotsV(i) = knotsI[i]; } knots = knotsV; - Kokkos::deep_copy(knots, host_knotsV(i)); + Kokkos::deep_copy(knots, host_knotsV); Kokkos::View knotsOffsetV("knotsOffset", 1); auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); @@ -55,7 +56,7 @@ class BSPlineKokkos2DView { } - BSplineKokkos2DView(std::vector& multiSplines) { + BSplineKokkos2D(std::vector& multiSplines) { //Loop over all the splines to know how much space to allocate int orderSize = 0; int ctrlPtsSize = 0; @@ -68,13 +69,13 @@ class BSPlineKokkos2DView { ctrlPtsSize += multiSplines[i].getCtrlPts().extent(0); cpOffsetSize += multiSplines[i].getCPOffset().extent(0); knotSize += multiSplines[i].getKnots().extent(0); - knotsOffsetSize += multiSpline[i].getKnotsOffset().extent(0); + knotsOffsetSize += multiSplines[i].getKnotsOffset().extent(0); } //Populate the views Kokkos::View orderV ("order", orderSize); Kokkos::View ctrlPtsV("ctrlPts", ctrlPtsSize); - Kokkos::View cPOffsetV("ctrlPtsOffset", cPOffsetSize); + Kokkos::View cPOffsetV("ctrlPtsOffset", cpOffsetSize); Kokkos::View knotsV("knots", knotSize); Kokkos::View knotsOffsetV("knotsOffset", knotsOffsetSize); @@ -108,10 +109,10 @@ class BSPlineKokkos2DView { mvCtrlPtsV(cPidx+j, 0) = mvDouble2DView(j, 0); mvCtrlPtsV(cPidx+j, 1) = mvDouble2DView(j, 1); } - cPidx += mvDouble2dView.extent(0); + cPidx += mvDouble2DView.extent(0); //Populate ctrlPtsOffset - intView = mutiSplines[i].getCPOffset(); + intView = multiSplines[i].getCPOffset(); mvIntView = Kokkos::create_mirror_view(intView); Kokkos::deep_copy(mvIntView, intView); @@ -131,7 +132,7 @@ class BSPlineKokkos2DView { kidx += doubleView.extent(0); //Populate knots offset - intView = multiSpliens[i].getKnotsOffset(); + intView = multiSplines[i].getKnotsOffset(); mvIntView = Kokkos::create_mirror_view(intView); Kokkos::deep_copy(mvIntView, intView); @@ -144,13 +145,13 @@ class BSPlineKokkos2DView { //Copy the data on host to device order = orderV; ctrlPts = ctrlPtsV; - cPOffset = cPOffset; + cpOffset = cPOffsetV; knots = knotsV; knotsOffset = knotsOffsetV; Kokkos::deep_copy(order, mvOrderV); Kokkos::deep_copy(ctrlPts, mvCtrlPtsV); - Kokkos::deep_copy(cPOffset, mvCPOffsetV); + Kokkos::deep_copy(cpOffset, mvCPOffsetV); Kokkos::deep_copy(knots, mvKnotsV); Kokkos::deep_copy(knotsOffset, mvKnotsOffsetV); @@ -169,11 +170,18 @@ class BSPlineKokkos2DView { auto mvCP1stDOffsetV = Kokkos::create_mirror_view(cP1stDOffsetV); auto mvCP2ndDOffsetV = Kokkos::create_mirror_view(cP2ndDOffsetV); - auto mvCPOffset = Kokkos::create_mirror_view(cPOffset); - Kokkos::deep_copy(mvCPOffset, cPOffset); + auto mvCPOffset = Kokkos::create_mirror_view(cpOffset); + if (mvCPOffset.extent(0) > 1) { - mvCP1stDOffsetV(i) = mvCPOffset(i)-1; - mvCP2ndDOffsetV(i) = mvCPOffset(i)-2; + Kokkos::deep_copy(mvCPOffset, cpOffset); + for (int i = 1; i < mvCPOffset.extent(0); i++) { + mvCP1stDOffsetV(i) = mvCPOffset(i)-1; + mvCP2ndDOffsetV(i) = mvCPOffset(i)-2; + } + } + else { + mvCP1stDOffsetV(0) = mvCPOffset(0)-1; + mvCP2ndDOffsetV(0) = mvCPOffset(0)-2; } auto mvOrder = Kokkos::create_mirror_view(order); @@ -187,7 +195,7 @@ class BSPlineKokkos2DView { //Calculate 1st derivative coef int offidx = 0; //Offset index int oidx = 0; //Order index - for (int i = 1; i < cltrPts1stDV.extent(0); i++) { + for (int i = 1; i < mvCtrlPts1stDV.extent(0); i++) { //We need to check whether we are on the border for the next spline in our structure if (i == mvCP1stDOffsetV(offidx)) { oidx++; @@ -200,14 +208,16 @@ class BSPlineKokkos2DView { } //Calculate 2nd derivative coef + Kokkos::View ctrlPts2ndDV("ctrlPts2ndDeriv", ctrlPts.extent(0)-(2*cpOffset.extent(0))); auto mvCtrlPts2ndDV = Kokkos::create_mirror_view(ctrlPts2ndDV); + for (int i = 1; i < ctrlPts1stDV.extent(0); i++) { if (i == mvCP2ndDOffsetV(offidx)) { oidx++; offidx++; continue; } - double delta = double(mvOrder-2) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i+1)); + double delta = double(mvOrder(oidx)-2) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i+1)); mvCtrlPts2ndDV(i, 0) = (mvCtrlPts(i, 0) - mvCtrlPts(i-1, 0)) * delta; mvCtrlPts2ndDV(i, 1) = (mvCtrlPts(i, 1) - mvCtrlPts(i-1, 1)) * delta; } @@ -227,7 +237,7 @@ class BSPlineKokkos2DView { //Accessors Kokkos::View getOrder() const {return order;} Kokkos::View getCtrlPts() const {return ctrlPts;} - Kokkos::View getCPOffset() const {return cPOffset;} + Kokkos::View getCPOffset() const {return cpOffset;} Kokkos::View getKnots() const {return knots;} Kokkos::View getKnotsOffset() const {return knotsOffset;} Kokkos::View getCP1stD() const {return ctrlPts1stD;} @@ -239,7 +249,7 @@ class BSPlineKokkos2DView { private: Kokkos::View order; Kokkos::View ctrlPts; - kokkos::View cpOffset; + Kokkos::View cpOffset; Kokkos::View knots; Kokkos::View knotsOffset; Kokkos::View ctrlPts1stD; diff --git a/testSplineKokkos2DBase.cpp b/testSplineKokkos2DBase.cpp new file mode 100644 index 0000000..c3d4a33 --- /dev/null +++ b/testSplineKokkos2DBase.cpp @@ -0,0 +1,64 @@ +//Constructor test for new representation of Kokkos spline +//We will be comparing this against the serial version +#include +#include "BSplineKokkos2D.h" +#include "BSpline.h" +#include "splineInterpolation.h" +#include "curveReader.h" + +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char* argv[]) { + //We check how many arguments are given + int retVal = 0; + if (argc != 3) { + std::cerr<< "Input arguments: " << std::endl; + std::cerr << "input csv need these columns: "; + std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; + return 1; + } + Kokkos::initialize(argc, argv); + { + + #ifdef KOKKOS_ENABLE_CUDA + #define MemSpace Kokkos::CudaSpace + #endif + #ifndef MemSpace + #define MemSpace Kokkos::HostSpace + #endif + + using ExecutionSpace = MemSpace::execution_space; + std::string inputCSV = argv[1]; + int extensionPos = inputCSV.rfind("."); + int slashPos = inputCSV.rfind("/"); + std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); + double expectedCurveLength = std::stod(argv[2]); + auto curve = CurveReader::readCurveInfo(inputCSV); + + //Construct BSpline2d object + SplineInterp::BSpline2d serialBSP; + if (curve.x.size() == 2) { + serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); + } else { + serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); + } + + std::vector ctrlPtsX, ctrlPtsY, knots, weight; + int order; + + serialBSP.x.getpara(order, ctrlPtsX, knots, weight); + serialBSP.y.getpara(order, ctrlPtsY, knots, weight); + + BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); + + } + Kokkos::finalize(); + return retVal; +} + From 2e44c755224ed8cc1a40f1e7886a1f3424fb91bb Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 21 Apr 2026 22:11:20 -0400 Subject: [PATCH 54/73] Test updated, single spline initialization ok --- testSplineKokkos2DBase.cpp | 43 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/testSplineKokkos2DBase.cpp b/testSplineKokkos2DBase.cpp index c3d4a33..0308969 100644 --- a/testSplineKokkos2DBase.cpp +++ b/testSplineKokkos2DBase.cpp @@ -14,6 +14,11 @@ #include #include +//For checking if the content of the splines are correct +// + +double EPSILON = 1e-12; + int main(int argc, char* argv[]) { //We check how many arguments are given int retVal = 0; @@ -57,6 +62,44 @@ int main(int argc, char* argv[]) { BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); + auto intView = Kokkos::create_mirror_view(kokkosBSP.getOrder()); + Kokkos::deep_copy(intView, kokkosBSP.getOrder()); + //Testing the order initialization + double diff = std::fabs(order - intView(0)); + if (diff > EPSILON) { + std::cout << "Order difference : " << diff << std::endl; + std::cout << "Serial: " << order << " Kokkos: " << intView(0) << std::endl; + retVal = 1; + } + + auto double2DView = Kokkos::create_mirror_view(kokkosBSP.getCtrlPts()); + Kokkos::deep_copy(double2DView, kokkosBSP.getCtrlPts()); + + //Testing ctrlPts initialization + double xDiff, yDiff; + for (int i = 0; i < ctrlPtsX.size(); i++) { + xDiff = std::fabs(ctrlPtsX[i] - double2DView(i, 0)); + yDiff = std::fabs(ctrlPtsY[i] - double2DView(i, 1)); + if (xDiff > EPSILON || yDiff > EPSILON) { + std::cout << "CtrlPts difference: x = " << xDiff << " y = " << yDiff << std::endl; + std::cout << "Serial: " << ctrlPtsX[i] << ", " << ctrlPtsY[i] << std::endl; + std::cout << "Kokkos: " << double2DView(i, 0) << ", " << double2DView(i, 1) << std::endl; + retVal = 1; + break; + } + } + + auto doubleView = Kokkos::create_mirror_view(kokkosBSP.getKnots()); + Kokkos::deep_copy(doubleView, kokkosBSP.getKnots()); + for (int i = 0; i < knots.size(); i++) { + diff = std::fabs(knots[i] - doubleView(i)); + if (diff > EPSILON) { + std::cout << "Knots difference: " << diff << std::endl; + std::cout << "Serial: " << knots[i] << std::endl; + std::cout << "Kokkos: " << doubleView(i) << std::endl; + } + } + } Kokkos::finalize(); return retVal; From 716bd6c8ad8f695692751e548e8aa3a215547bfa Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 21 Apr 2026 22:44:41 -0400 Subject: [PATCH 55/73] add 1st pass eval1stDeriv, no compile err --- BSplineKokkos2D.h | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h index 6838410..e284cc3 100644 --- a/BSplineKokkos2D.h +++ b/BSplineKokkos2D.h @@ -234,6 +234,58 @@ class BSplineKokkos2D { ctrlPts2ndD = ctrlPts2ndDV; } + KOKKOS_FUNCTION void evalDeBoor(double x, int splineo, int lKnot, Kokkos::View result, const Kokkos::View order, const Kokkos::View knots, const Kokkos::View ctrlPts_1stD) const { + //DeBoor's algorithm for BSpline 1st deriv calculation + int order_t = lKnot; + int leftPt = 0; + + while (x > knots(lKnot+1)) { + lKnot++; + leftPt++; + } + + //Allocate temporary points + double ptsX[3]; + double ptsY[3]; + + int idx = 0; + for (int i = leftPt; i < leftPt + order_t; i++) { + ptsX[idx] = ctrlPts_1stD(i, 0); + ptsY[idx] = ctrlPts_1stD(i, 1); + idx++; + } + + auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order+2, lKnot+order_t)); + + //Calculation loop + for (int r = 1; r <= order_t; r++) { + for(int i = order_t-1; i >= r; i--) { + double alpha; + if (localKnots(i-1) - localKnots(i+order_t-r-1) > 1e-12) { + alpha = 0; + } + else { + alpha = (x - localKnots(i-1)) / (knots(i+order_t-r-1) - knots(i-1)); + } + ptsX[i] = (1. - alpha) * ptsX[i-1]+alpha * ptsX[i]; + ptsY[i] = (1. - alpha) * ptsY[i-1]+alpha * ptsY[i]; + } + + result(0) = ptsX[order_t-1]; + result(1) = ptsY[order_t-1]; + } + } + + Kokkos::View eval1stDeriv(std::vector xVals, int splineo) const { + int lKnot; + Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); + lKnot--; + Kokkos::View res("result", 2); + Kokkos::parallel_for("parallel evalDeBoors", xVals.size(), KOKKOS_CLASS_LAMBDA(int i){ + evalDeBoor(xVals[i], splineo, lKnot, res, order, knots, ctrlPts1stD); + }); + return res; + } //Accessors Kokkos::View getOrder() const {return order;} Kokkos::View getCtrlPts() const {return ctrlPts;} From 9d071842009218caadbdb8b0deb0cda0feb27d96 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Tue, 21 Apr 2026 23:02:38 -0400 Subject: [PATCH 56/73] 1st pass test, no compile & not in CMakeLists --- testKokkos2D1stDeriv.cpp | 83 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 testKokkos2D1stDeriv.cpp diff --git a/testKokkos2D1stDeriv.cpp b/testKokkos2D1stDeriv.cpp new file mode 100644 index 0000000..8ee1686 --- /dev/null +++ b/testKokkos2D1stDeriv.cpp @@ -0,0 +1,83 @@ +#include +#include "BSplineKokkos.h" +#include "BSpline.h" +#include + +#include "splineInterpolation.h" +#include "curveReader.h" +#include +#include +#include +#include +#include +#include + +double EPSILON = 1e-12; + +int main(int argc, char* argv[]) { + int retVal; + if (argc != 3) { + std::cerr<< "Input arguments: " << std::endl; + std::cerr << "input csv need these columns: "; + std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; + return 1; + } + + Kokkos::initialize(argc, argv); + { + #ifdef KOKKOS_ENABLE_CUDA + #define MemSpace Kokkos::CudaSpace + #endif + #ifndef MemSpace + #define MemSpace Kokkos::HostSpace + #endif + + using ExecutionSpace = MemSpace::execution_space; + + std::string inputCSV = argv[1]; + int extensionPos = inputCSV.rfind("."); + int slashPos = inputCSV.rfind("/"); + std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); + double expectedCurveLength = std::stod(argv[2]); + auto curve = CurveReader::readCurveInfo(inputCSV); + + //Construct BSpline2d object + SplineInterp::BSpline2d serialBSP; + if (curve.x.size() == 2) { + serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); + } else { + serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); + } + + std::vector ctrlPtsX, ctrlPtsY, knots, weight; + int order; + + //Get the info from serial spline, we will feed this to kokkos spline + serialBSP.x.getpara(order, ctrlPtsX, knots, weight); + serialBSP.y.getpara(order, ctrlPtsY, knots, weight); + + BSplineKokkos kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); + + std::vector evalAt = {0, 0.2, 0.41, 0.5, 0.66, 0.73, 0.75, 0.89, 0.94, 1}; + for (int i = 0; i < 10; i++) { + double derivX = serialBSP.x.evalFirstDeriv(evalAt[i]); + double derivY = serialBSP.y.evalFirstDeriv(evalAt[i]); + Kokkos::View res("deriv result", 2); + res = kokkosBSP.eval1stDeriv({evalAt[i]}, 0); + auto mvRes = Kokkos::create_mirror_view(res); + Kokkos::deep_copy(mvRes, res); + + double xDiff = std::fabs(derivX) - std::fabs(mvRes(0)); + double yDiff = std::fabs(derivY) - std::fabs(mvRes(1)); + if (xDiff > EPSILON || yDiff > EPSILON) { + std::cout << "Test " << i+1 << " failed, eval at: " << evalAt[i] << std::endl; + std::cout << "Difference: x = " << xDiff << " y = " << yDiff << std::endl; + std::cout << "SERIAL 1st deriv: x = " << derivX << " y = " << derivY << std::endl; + std::cout << "KOKKOS 1st deriv: x = " << mvRes(0) << " y = " << mvRes(1) << std::endl; + retVal = 1; + } + } + } + Kokkos::finalize(); + return retVal; +} From 156d619eb0ad2ca0f9019c5f87b27be1a868d1a5 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Thu, 30 Apr 2026 16:54:04 -0400 Subject: [PATCH 57/73] Fixed 1st derivative coeff calculation --- BSplineKokkos2D.h | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h index e284cc3..fa34760 100644 --- a/BSplineKokkos2D.h +++ b/BSplineKokkos2D.h @@ -195,16 +195,12 @@ class BSplineKokkos2D { //Calculate 1st derivative coef int offidx = 0; //Offset index int oidx = 0; //Order index - for (int i = 1; i < mvCtrlPts1stDV.extent(0); i++) { + for (int i = 1; i < mvCtrlPts1stDV.extent(0)+1; i++) { //We need to check whether we are on the border for the next spline in our structure - if (i == mvCP1stDOffsetV(offidx)) { - oidx++; - offidx++; - continue; //Skip to the next - } - double delta = double(mvOrder(oidx-1)) / (mvKnots(i+mvOrder(oidx-1)) - mvKnots(i)); - mvCtrlPts1stDV(i, 0) = (mvCtrlPts(i, 0) - mvCtrlPts(i-1, 0))*delta; - mvCtrlPts1stDV(i, 1) = (mvCtrlPts(i, 1) - mvCtrlPts(i-1, 1))*delta; + double delta = double(mvOrder(oidx)-1) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i)); + + mvCtrlPts1stDV(i-1, 0) = (mvCtrlPts(i, 0) - mvCtrlPts(i-1, 0))*delta; + mvCtrlPts1stDV(i-1, 1) = (mvCtrlPts(i, 1) - mvCtrlPts(i-1, 1))*delta; } //Calculate 2nd derivative coef @@ -218,6 +214,7 @@ class BSplineKokkos2D { continue; } double delta = double(mvOrder(oidx)-2) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i+1)); + mvCtrlPts2ndDV(i, 0) = (mvCtrlPts(i, 0) - mvCtrlPts(i-1, 0)) * delta; mvCtrlPts2ndDV(i, 1) = (mvCtrlPts(i, 1) - mvCtrlPts(i-1, 1)) * delta; } @@ -232,6 +229,8 @@ class BSplineKokkos2D { cp2ndDOffset = cP2ndDOffsetV; ctrlPts1stD = ctrlPts1stDV; ctrlPts2ndD = ctrlPts2ndDV; + + } KOKKOS_FUNCTION void evalDeBoor(double x, int splineo, int lKnot, Kokkos::View result, const Kokkos::View order, const Kokkos::View knots, const Kokkos::View ctrlPts_1stD) const { @@ -255,7 +254,7 @@ class BSplineKokkos2D { idx++; } - auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order+2, lKnot+order_t)); + auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order_t+2, lKnot+order_t)); //Calculation loop for (int r = 1; r <= order_t; r++) { From 8d5688214bf58d91d09b429735b63342e82a5886 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Thu, 30 Apr 2026 17:20:12 -0400 Subject: [PATCH 58/73] Fixed 2nd deriv coeff calculation --- BSplineKokkos2D.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h index fa34760..ce03b5a 100644 --- a/BSplineKokkos2D.h +++ b/BSplineKokkos2D.h @@ -196,6 +196,11 @@ class BSplineKokkos2D { int offidx = 0; //Offset index int oidx = 0; //Order index for (int i = 1; i < mvCtrlPts1stDV.extent(0)+1; i++) { + if (i == mvCP1stDOffsetV(offidx)+1) { + oidx++; + offidx++; + continue; + } //We need to check whether we are on the border for the next spline in our structure double delta = double(mvOrder(oidx)-1) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i)); @@ -207,16 +212,18 @@ class BSplineKokkos2D { Kokkos::View ctrlPts2ndDV("ctrlPts2ndDeriv", ctrlPts.extent(0)-(2*cpOffset.extent(0))); auto mvCtrlPts2ndDV = Kokkos::create_mirror_view(ctrlPts2ndDV); + offidx = 0; + oidx = 0; for (int i = 1; i < ctrlPts1stDV.extent(0); i++) { - if (i == mvCP2ndDOffsetV(offidx)) { + if (i == mvCP2ndDOffsetV(offidx)+2) { oidx++; offidx++; continue; } double delta = double(mvOrder(oidx)-2) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i+1)); - mvCtrlPts2ndDV(i, 0) = (mvCtrlPts(i, 0) - mvCtrlPts(i-1, 0)) * delta; - mvCtrlPts2ndDV(i, 1) = (mvCtrlPts(i, 1) - mvCtrlPts(i-1, 1)) * delta; + mvCtrlPts2ndDV(i-1, 0) = (mvCtrlPts1stDV(i, 0) - mvCtrlPts1stDV(i-1, 0)) * delta; + mvCtrlPts2ndDV(i-1, 1) = (mvCtrlPts1stDV(i, 1) - mvCtrlPts1stDV(i-1, 1)) * deltag } //Copy to device From 036bbb3bf2d975b7cf7e5646bd8a5654e4e72d8c Mon Sep 17 00:00:00 2001 From: Hsieh Date: Thu, 30 Apr 2026 17:56:00 -0400 Subject: [PATCH 59/73] 1st deriv test pass both NATIVE & AMPERE86 builds --- testKokkos2D1stDeriv.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testKokkos2D1stDeriv.cpp b/testKokkos2D1stDeriv.cpp index 8ee1686..03bbb7c 100644 --- a/testKokkos2D1stDeriv.cpp +++ b/testKokkos2D1stDeriv.cpp @@ -1,5 +1,5 @@ #include -#include "BSplineKokkos.h" +#include "BSplineKokkos2D.h" #include "BSpline.h" #include @@ -56,7 +56,7 @@ int main(int argc, char* argv[]) { serialBSP.x.getpara(order, ctrlPtsX, knots, weight); serialBSP.y.getpara(order, ctrlPtsY, knots, weight); - BSplineKokkos kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); + BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); std::vector evalAt = {0, 0.2, 0.41, 0.5, 0.66, 0.73, 0.75, 0.89, 0.94, 1}; for (int i = 0; i < 10; i++) { From 2089e1a89e28b8d67c4537aa26508d559080e1fc Mon Sep 17 00:00:00 2001 From: Hsieh Date: Thu, 30 Apr 2026 18:02:11 -0400 Subject: [PATCH 60/73] Add 1st & 2nd coef test pass ampere & native build --- testSplineKokkos2DBase.cpp | 54 +++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/testSplineKokkos2DBase.cpp b/testSplineKokkos2DBase.cpp index 0308969..ccf97d5 100644 --- a/testSplineKokkos2DBase.cpp +++ b/testSplineKokkos2DBase.cpp @@ -37,8 +37,9 @@ int main(int argc, char* argv[]) { #ifndef MemSpace #define MemSpace Kokkos::HostSpace #endif - + using ExecutionSpace = MemSpace::execution_space; + std::string inputCSV = argv[1]; int extensionPos = inputCSV.rfind("."); int slashPos = inputCSV.rfind("/"); @@ -85,10 +86,10 @@ int main(int argc, char* argv[]) { std::cout << "Serial: " << ctrlPtsX[i] << ", " << ctrlPtsY[i] << std::endl; std::cout << "Kokkos: " << double2DView(i, 0) << ", " << double2DView(i, 1) << std::endl; retVal = 1; - break; } } + //Test knots initialization auto doubleView = Kokkos::create_mirror_view(kokkosBSP.getKnots()); Kokkos::deep_copy(doubleView, kokkosBSP.getKnots()); for (int i = 0; i < knots.size(); i++) { @@ -96,10 +97,57 @@ int main(int argc, char* argv[]) { if (diff > EPSILON) { std::cout << "Knots difference: " << diff << std::endl; std::cout << "Serial: " << knots[i] << std::endl; - std::cout << "Kokkos: " << doubleView(i) << std::endl; + std::cout << "Kokkos: " << doubleView(i) << std::endl; + retVal = 1; + } + } + + //Test 1st deriv coef initialization + Kokkos::View coef ("getCPCoe2", kokkosBSP.getCP1stD().extent(0)); + + coef = kokkosBSP.getCP1stD(); + + auto mv_coef = Kokkos::create_mirror_view(coef); + + Kokkos::deep_copy(mv_coef, coef); + + std::vector serialCoefX = serialBSP.x.getCtrlPts_1st(); + std::vector serialCoefY = serialBSP.y.getCtrlPts_1st(); + + for (int i = 0; i < serialCoefX.size(); i++) { + double diffX = std::fabs(serialCoefX[i] - mv_coef(i, 0)); + double diffY = std::fabs(serialCoefY[i] - mv_coef(i, 1)); + if (diffX > EPSILON || diffY > EPSILON) { + std::cout << "diffX: " << diffX << std::endl; + std::cout << "diffY: " << diffY << std::endl; + std::cout << "Serial 1st coef: " << serialCoefX[i] << ", " << serialCoefY[i] << std::endl; + std::cout << "Kokkos 1st coef: " << mv_coef(i, 0)<< ", " << mv_coef(i, 1) << std::endl; + retVal = 1; } + } + Kokkos::Viewcoef2 ("getCPCoe2", kokkosBSP.getCP2ndD().extent(0)); + coef2 = kokkosBSP.getCP2ndD(); + + mv_coef = Kokkos::create_mirror_view(coef2); + + Kokkos::deep_copy(mv_coef, coef2); + + serialCoefX = serialBSP.x.getCtrlPts_2nd(); + serialCoefY = serialBSP.y.getCtrlPts_2nd(); + for (int i = 0; i < serialCoefX.size(); i++) { + double diffX = std::fabs(serialCoefX[i] - mv_coef(i, 0)); + double diffY = std::fabs(serialCoefY[i] - mv_coef(i, 1)); + if (diffX > EPSILON || diffY > EPSILON) { + std::cout << "diffX: " << diffX << std::endl; + std::cout << "diffY: " << diffY << std::endl; + std::cout << "Serial 2nd coef: " << serialCoefX[i] << ", " << serialCoefY[i] << std::endl; + std::cout << "Kokkos 2nd coef: " << mv_coef(i, 0)<< ", " << mv_coef(i, 1) << std::endl; + retVal = 1; + } + } + } Kokkos::finalize(); return retVal; From 8f25efe8a77427d1292afd9f9211113e03220dcc Mon Sep 17 00:00:00 2001 From: Hsieh Date: Thu, 30 Apr 2026 18:04:49 -0400 Subject: [PATCH 61/73] Fixed 1st & 2nd coef calculation --- BSplineKokkos2D.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h index ce03b5a..4be0122 100644 --- a/BSplineKokkos2D.h +++ b/BSplineKokkos2D.h @@ -223,7 +223,7 @@ class BSplineKokkos2D { double delta = double(mvOrder(oidx)-2) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i+1)); mvCtrlPts2ndDV(i-1, 0) = (mvCtrlPts1stDV(i, 0) - mvCtrlPts1stDV(i-1, 0)) * delta; - mvCtrlPts2ndDV(i-1, 1) = (mvCtrlPts1stDV(i, 1) - mvCtrlPts1stDV(i-1, 1)) * deltag + mvCtrlPts2ndDV(i-1, 1) = (mvCtrlPts1stDV(i, 1) - mvCtrlPts1stDV(i-1, 1)) * delta; } //Copy to device From 59d3ba649af5f47c91ff1d83752fa2a9e296a93e Mon Sep 17 00:00:00 2001 From: Hsieh Date: Thu, 30 Apr 2026 20:58:54 -0400 Subject: [PATCH 62/73] First pass implementation for 2nd deriv --- BSplineKokkos2D.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h index 4be0122..755cdfb 100644 --- a/BSplineKokkos2D.h +++ b/BSplineKokkos2D.h @@ -292,6 +292,68 @@ class BSplineKokkos2D { }); return res; } + + + //Second derivative calculation + KOKKOS_FUNCTION void evalDeBoor2(double x, int splineo, int lKnot, Kokkos::View result, const Kokkos::View order, const Kokkos::View knots, const Kokkos::View ctrlPts_2ndD) const { + if (order(splineo) == 2) { + return 0; + } + + int order_t = lKnot-1; + int leftPt = 0; + + while (knots(lKnot+1) < x) { + lKnot++; + leftPt++; + } + + double ptsX[3]; + double ptsY[3]; + + int idx = 0; + for (int i = leftPt; i < leftPt+order_t; i++) { + ptsX[idx] = ctrlPts_2ndD(i, 0); + ptsY[idx] = ctrlPts_2ndD(i, 1); + idx++; + } + + auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order_t+2, lKnot+order_t)); + + for (int r = 1; r <= ordet_t; r++) { + for (int i = order_t-1; i>= r; i++) { + double aLeft = localKnots(i-1); + double aRight = localKnots(i+order_t-r-1); + double alpha; + if (aLeft == aRight) { + alpha = 0; + } + else { + alpha = (x - aLeft) / (aRight - aLeft); + } + + ptsX[i] = (1. - alpha) * ptsX[i-1] + alpha * ptsX[i]; + ptsY[i] = (1. - alpha) * ptsY[i-1] + alpha * ptsY[i]; + } + } + + result(0) = ptsX[order_t-1]; + result(1) = ptsY[order_t-1]; + + } + + Kokkos::View eval2ndDeriv(std::vector xVals, int splineo) const { + int lKnot; + Kokkos::deep_copy(order, splineo); + lKnot--; + Kokkos::View res("result", 2); + Kokkos::parallel_for("parallel evalDeBoors 2", xVals.size(), KOKKOS_CLASS_LAMBDA(int i) { + evalDeBoor2(xVals[i], splineo, lKnot, res, order, knots, ctrlPts2ndD); + }); + return res; + } + + //Accessors Kokkos::View getOrder() const {return order;} Kokkos::View getCtrlPts() const {return ctrlPts;} From c7f583c9d0fdbadd7af340bcc6696b6b96946eb2 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Thu, 30 Apr 2026 21:29:26 -0400 Subject: [PATCH 63/73] First pass implementation of 2nd deriv test --- testKokkos2D2ndDeriv.cpp | 81 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 testKokkos2D2ndDeriv.cpp diff --git a/testKokkos2D2ndDeriv.cpp b/testKokkos2D2ndDeriv.cpp new file mode 100644 index 0000000..b2ea287 --- /dev/null +++ b/testKokkos2D2ndDeriv.cpp @@ -0,0 +1,81 @@ +#include +#include "BSplineKokkos2D.h" +#include "BSpline.h" +#include + +#include "splineInterpolation.h" +#include "curveReader.h" +#include +#include +#include +#include +#include +#include + +double EPSILON = 1e-12; + +int main(int argc, char* argv[]) { + int retVal = 0; + if (argc != 3) { + std::cerr<< "Input arguments: " << std::endl; + std::cerr << "input csv need these columns: "; + std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; + return 1; + } + + Kokkos::initialize(argc, argv); + { + #ifdef KOKKOS_ENABLE_CUDA + #endif + #ifndef MemSpace + #define MemSpace Kokkos::HostSpace + #endif + + std::string inputCSV = argv[1]; + int extensionPos = inputCSV.rfind("."); + int slashPos = input.rfind("/"); + std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); + double expectedCurveLength = std::stod(argv[2]); + auto curve = CurveReader::readCurveInfo(inputCSV); + + SplineInterp::BSpline2d serialBSP; + if (curve.x.size() == 2) { + serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); + } + else { + serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); + } + + std::vector ctrlPtsX, ctrlPtsY, knots, weight; + int order; + serialBSP.x.getpara(order, ctrlPtsX, knots, weight); + serialBSP.y.getpara(order, ctrlPtsY, knots, weight); + + BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); + + std::vector evalAt = {0, 0.2, 0.41, 0.5, 0.66, 0.73, 0.75, 0.89, 0.94, 1}; + for (int i = 0; i < 10; i++) { + double derivX = serialBSP.x.evalSecondDeriv(evalAt[i]); + double derivY = serialBSP.y.evalSecondDeriv(evalAt[i]); + + Kokkos::View res("Result", 2); + res = kokkosBSP.eval2ndDeriv({evalAt[i]}, 0); + auto mvRes = Kokkos::create_mirror_view(res); + Kokkos::deep_copy(mvRes, res); + + double xDiff = std::fabs(derivX - mvRes(0)); + double yDiff = std::fabs(derivY - mvRes(1)); + + if (xDiff > EPSILON || yDiff > EPSILON) { + std::cout << "Test " << i+1 << " failed, eval at: " << evalAt[i] << std::endl; + std::cout << "Difference: x = " << xDiff << " y = " << derivY << std::endl; + std::cout << "SERIAL 2nd deriv: x = " << derivX << ", " << derivY << std::endl; + std::cout << "KOKKOS 2nd deriv: x = " << mvRes(0) << ", " << mvRes(1) << std::endl; + retVal = 1; + } + } + } + Kokkos::finalize(); + return retVal; + +} From 91e8c8ff30550397d78752365f440a8420b010bd Mon Sep 17 00:00:00 2001 From: Hsieh Date: Thu, 30 Apr 2026 22:00:05 -0400 Subject: [PATCH 64/73] Bug fixes, 2nd deriv test segfaults --- BSplineKokkos2D.h | 14 +++++++++----- CMakeLists.txt | 30 ++++++++++++++++++++++++++++-- testKokkos2D2ndDeriv.cpp | 7 +++++-- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h index 755cdfb..6120eea 100644 --- a/BSplineKokkos2D.h +++ b/BSplineKokkos2D.h @@ -297,7 +297,9 @@ class BSplineKokkos2D { //Second derivative calculation KOKKOS_FUNCTION void evalDeBoor2(double x, int splineo, int lKnot, Kokkos::View result, const Kokkos::View order, const Kokkos::View knots, const Kokkos::View ctrlPts_2ndD) const { if (order(splineo) == 2) { - return 0; + result(0) = 0; + result(1) = 0; + return; } int order_t = lKnot-1; @@ -308,8 +310,8 @@ class BSplineKokkos2D { leftPt++; } - double ptsX[3]; - double ptsY[3]; + double ptsX[2]; + double ptsY[2]; int idx = 0; for (int i = leftPt; i < leftPt+order_t; i++) { @@ -318,9 +320,11 @@ class BSplineKokkos2D { idx++; } + + auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order_t+2, lKnot+order_t)); - for (int r = 1; r <= ordet_t; r++) { + for (int r = 1; r <= order_t; r++) { for (int i = order_t-1; i>= r; i++) { double aLeft = localKnots(i-1); double aRight = localKnots(i+order_t-r-1); @@ -344,7 +348,7 @@ class BSplineKokkos2D { Kokkos::View eval2ndDeriv(std::vector xVals, int splineo) const { int lKnot; - Kokkos::deep_copy(order, splineo); + Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); lKnot--; Kokkos::View res("result", 2); Kokkos::parallel_for("parallel evalDeBoors 2", xVals.size(), KOKKOS_CLASS_LAMBDA(int i) { diff --git a/CMakeLists.txt b/CMakeLists.txt index d77737b..3200706 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,10 @@ project(simLandIceMeshGen VERSION 0.0.1 LANGUAGES CXX) enable_testing() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +#Enabling Address Sanitizer (ASan) +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") +#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") + option(USE_SIMMODSUITE "Enable SimModSuite support" ON) if(USE_SIMMODSUITE) @@ -33,6 +37,7 @@ target_link_libraries(splineKokkos PRIVATE Kokkos::kokkos) add_library(splineKokkos2D BSplineKokkos2D.cpp) target_link_libraries(splineKokkos2D PRIVATE Kokkos::kokkos) + set(testDataDir ${CMAKE_CURRENT_SOURCE_DIR}/contour_test_data) if(USE_SIMMODSUITE) @@ -190,7 +195,7 @@ add_executable(testKokkos1stDerivative testKokkos1stDerivative.cpp) target_link_libraries(testKokkos1stDerivative PRIVATE splineInterp curveReader modelGen2d splineKokkos Kokkos::kokkos) add_test(NAME testKokkos1stDerivativeStraightEdge - COMMAND ./testKokkos1stDerivative contour_test_data/testCurveStrightLine.csv 9) + COMMAND ./testKokkos1stDerivative contour_test_data/testCurveStraightLine.csv 9) add_test(NAME testKokkos1stDerivativeEdge2Pts COMMAND ./testKokkos1stDerivative contour_test_data/testCurve2pts.csv 1) @@ -202,8 +207,29 @@ add_test(NAME testKokkos1stDerivativeSingleEdge add_executable(testSplineKokkos2DBase testSplineKokkos2DBase.cpp) target_link_libraries(testSplineKokkos2DBase PRIVATE splineInterp curveReader modelGen2d splineKokkos2D Kokkos::kokkos) add_test(NAME testSplineKokkos2DStraightEdge - COMMAND ./testSplineKokkos2DBase contour_test_data/testCurveStrightLine.csv 9) + COMMAND ./testSplineKokkos2DBase contour_test_data/testCurveStraightLine.csv 9) add_test(NAME testSplineKokkos2D2Pts COMMAND ./testSplineKokkos2DBase contour_test_data/testCurve2pts.csv 1) add_test(NAME testSplineKokkos2DSingleEdge COMMAND ./testSplineKokkos2DBase ${testDataDir}/testCurveSplineFitting.csv 12.2685) + +#TEST FOR BSPLINEKOKKOS2D 1ST DERIVATIVE +add_executable(testKokkos2D1stDeriv testKokkos2D1stDeriv.cpp) +target_link_libraries(testKokkos2D1stDeriv PRIVATE splineInterp curveReader modelGen2d splineKokkos2D Kokkos::kokkos) +add_test(NAME testDeriv2DStraightEdge + COMMAND ./testKokkos2D1stDeriv contour_test_data/testCurveStraightLine.csv 9) +add_test(NAME testDeriv2D2Pts + COMMAND ./testKokkos2D1stDeriv contour_test_data/testCurve2pts.csv 1) +add_test(NAME testDeriv2DSingleEdge + COMMAND ./testKokkos2D1stDeriv ${testDataDir}/testCurveSplineFitting.csv 12.2685) + +#TEST FOR BSPLINEKOKKOS2D 2ND DERIVATIVE +add_executable(testKokkos2D2ndDeriv testKokkos2D2ndDeriv.cpp) +target_link_libraries(testKokkos2D2ndDeriv PRIVATE splineInterp curveReader modelGen2d splineKokkos2D Kokkos::kokkos) +add_test(NAME test2NDDeriv2DStraightEdge + COMMAND ./testKokkos2D2ndDeriv contour_test_data/testCurveStraightLine.csv 9) +add_test(NAME test2NDDeriv2D2Pts + COMMAND ./testKokkos2D2ndDeriv contour_test_data/testCurve2pts.csv 1) +add_test(NAME test2NDDerive2DSingleEdge + COMMAND ./testKokkos2D2ndDeriv contour_test_data/testSplineFitting.csv 12.2685) + diff --git a/testKokkos2D2ndDeriv.cpp b/testKokkos2D2ndDeriv.cpp index b2ea287..8d1bfe0 100644 --- a/testKokkos2D2ndDeriv.cpp +++ b/testKokkos2D2ndDeriv.cpp @@ -26,14 +26,17 @@ int main(int argc, char* argv[]) { Kokkos::initialize(argc, argv); { #ifdef KOKKOS_ENABLE_CUDA - #endif + #define MemSpace Kokkos::CudaSpace + #endif #ifndef MemSpace #define MemSpace Kokkos::HostSpace #endif + using ExecutionSpace = MemSpace::execution_space; + std::string inputCSV = argv[1]; int extensionPos = inputCSV.rfind("."); - int slashPos = input.rfind("/"); + int slashPos = inputCSV.rfind("/"); std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); double expectedCurveLength = std::stod(argv[2]); auto curve = CurveReader::readCurveInfo(inputCSV); From 54ec379c5e3b5d84584a50e4ee3438c3a379024f Mon Sep 17 00:00:00 2001 From: Hsieh Date: Fri, 1 May 2026 09:00:43 -0400 Subject: [PATCH 65/73] Fixed nested forloop, all serial ok, fail parallel --- BSplineKokkos2D.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h index 6120eea..5a16bfb 100644 --- a/BSplineKokkos2D.h +++ b/BSplineKokkos2D.h @@ -310,8 +310,8 @@ class BSplineKokkos2D { leftPt++; } - double ptsX[2]; - double ptsY[2]; + double ptsX[3]; + double ptsY[3]; int idx = 0; for (int i = leftPt; i < leftPt+order_t; i++) { @@ -320,17 +320,15 @@ class BSplineKokkos2D { idx++; } - - auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order_t+2, lKnot+order_t)); for (int r = 1; r <= order_t; r++) { - for (int i = order_t-1; i>= r; i++) { + for (int i = order_t-1; i >= r; i--) { double aLeft = localKnots(i-1); double aRight = localKnots(i+order_t-r-1); double alpha; if (aLeft == aRight) { - alpha = 0; + alpha = 0.; } else { alpha = (x - aLeft) / (aRight - aLeft); From f2f91ce33e44db1ad8351d7b1ee268e00bb5f602 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Fri, 1 May 2026 11:58:50 -0400 Subject: [PATCH 66/73] Change deriv input to view, all test in cpu&gpu ok --- BSplineKokkos2D.h | 8 ++++---- testKokkos2D1stDeriv.cpp | 9 ++++++++- testKokkos2D2ndDeriv.cpp | 8 +++++++- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h index 5a16bfb..582bc30 100644 --- a/BSplineKokkos2D.h +++ b/BSplineKokkos2D.h @@ -282,13 +282,13 @@ class BSplineKokkos2D { } } - Kokkos::View eval1stDeriv(std::vector xVals, int splineo) const { + Kokkos::View eval1stDeriv(Kokkos::View xVals, int splineo) const { int lKnot; Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); lKnot--; Kokkos::View res("result", 2); Kokkos::parallel_for("parallel evalDeBoors", xVals.size(), KOKKOS_CLASS_LAMBDA(int i){ - evalDeBoor(xVals[i], splineo, lKnot, res, order, knots, ctrlPts1stD); + evalDeBoor(xVals(i), splineo, lKnot, res, order, knots, ctrlPts1stD); }); return res; } @@ -344,13 +344,13 @@ class BSplineKokkos2D { } - Kokkos::View eval2ndDeriv(std::vector xVals, int splineo) const { + Kokkos::View eval2ndDeriv(Kokkos::View xVals, int splineo) const { int lKnot; Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); lKnot--; Kokkos::View res("result", 2); Kokkos::parallel_for("parallel evalDeBoors 2", xVals.size(), KOKKOS_CLASS_LAMBDA(int i) { - evalDeBoor2(xVals[i], splineo, lKnot, res, order, knots, ctrlPts2ndD); + evalDeBoor2(xVals(i), splineo, lKnot, res, order, knots, ctrlPts2ndD); }); return res; } diff --git a/testKokkos2D1stDeriv.cpp b/testKokkos2D1stDeriv.cpp index 03bbb7c..d1f98f7 100644 --- a/testKokkos2D1stDeriv.cpp +++ b/testKokkos2D1stDeriv.cpp @@ -62,8 +62,15 @@ int main(int argc, char* argv[]) { for (int i = 0; i < 10; i++) { double derivX = serialBSP.x.evalFirstDeriv(evalAt[i]); double derivY = serialBSP.y.evalFirstDeriv(evalAt[i]); + Kokkos::View res("deriv result", 2); - res = kokkosBSP.eval1stDeriv({evalAt[i]}, 0); + Kokkos::View xVals ("paraCoor", 1); + auto mvXVals = Kokkos::create_mirror_view(xVals); + mvXVals(0) = evalAt[i]; + Kokkos::deep_copy(xVals, mvXVals); + + res = kokkosBSP.eval1stDeriv(xVals, 0); + auto mvRes = Kokkos::create_mirror_view(res); Kokkos::deep_copy(mvRes, res); diff --git a/testKokkos2D2ndDeriv.cpp b/testKokkos2D2ndDeriv.cpp index 8d1bfe0..d40847f 100644 --- a/testKokkos2D2ndDeriv.cpp +++ b/testKokkos2D2ndDeriv.cpp @@ -62,7 +62,13 @@ int main(int argc, char* argv[]) { double derivY = serialBSP.y.evalSecondDeriv(evalAt[i]); Kokkos::View res("Result", 2); - res = kokkosBSP.eval2ndDeriv({evalAt[i]}, 0); + + Kokkos::View xVals("paraCoor", 1); + auto mvXVals = Kokkos::create_mirror_view(xVals); + mvXVals(0) = evalAt[i]; + Kokkos::deep_copy(xVals, mvXVals); + + res = kokkosBSP.eval2ndDeriv(xVals, 0); auto mvRes = Kokkos::create_mirror_view(res); Kokkos::deep_copy(mvRes, res); From 72d00370132f14e6e71f35f165b63d2660317814 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Mon, 4 May 2026 13:44:31 -0400 Subject: [PATCH 67/73] Attempt to format the functions --- BSplineKokkos2D.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h index 582bc30..1ed24ec 100644 --- a/BSplineKokkos2D.h +++ b/BSplineKokkos2D.h @@ -281,15 +281,15 @@ class BSplineKokkos2D { result(1) = ptsY[order_t-1]; } } - + Kokkos::View eval1stDeriv(Kokkos::View xVals, int splineo) const { - int lKnot; + int lKnot; Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); lKnot--; Kokkos::View res("result", 2); Kokkos::parallel_for("parallel evalDeBoors", xVals.size(), KOKKOS_CLASS_LAMBDA(int i){ evalDeBoor(xVals(i), splineo, lKnot, res, order, knots, ctrlPts1stD); - }); + v}); return res; } From a25f24b4f906aa7fa03824b5a2b0642bf3d57112 Mon Sep 17 00:00:00 2001 From: hsiehhRPI <112642746+hsiehhRPI@users.noreply.github.com> Date: Mon, 4 May 2026 13:48:51 -0400 Subject: [PATCH 68/73] Update BSplineKokkos2D.h Fixed indentation for formatting --- BSplineKokkos2D.h | 620 +++++++++++++++++++++++----------------------- 1 file changed, 309 insertions(+), 311 deletions(-) diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h index 1ed24ec..fc661e2 100644 --- a/BSplineKokkos2D.h +++ b/BSplineKokkos2D.h @@ -14,345 +14,343 @@ class BSplineKokkos2D { using MemSpace = typename ExecutionSpace::memory_space; BSplineKokkos2D(int order_p, std::vector& ctrlPts_x, std::vector& ctrlPts_y, std::vector& knotsI) { - Kokkos::View orderV("Orders", 1); - auto host_orderV = Kokkos::create_mirror_view(orderV); - host_orderV(0) = order_p; - order = orderV; - Kokkos::deep_copy(order, host_orderV); - - Kokkos::View ctrlPtsV("ctrlPts", ctrlPts_x.size()); - auto host_ctrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); - for (int i = 0; i < ctrlPts_x.size(); i++) { - host_ctrlPtsV(i, 0) = ctrlPts_x[i]; - host_ctrlPtsV(i, 1) = ctrlPts_y[i]; - } - ctrlPts = ctrlPtsV; - Kokkos::deep_copy(ctrlPts, host_ctrlPtsV); - - Kokkos::View cpOffsetV("cpOffset", 1); - auto host_cpOffsetV = Kokkos::create_mirror_view(cpOffsetV); - host_cpOffsetV(0) = ctrlPts_x.size(); - host_cpOffsetV(0) = ctrlPts_x.size(); - - cpOffset = cpOffsetV; - Kokkos::deep_copy(cpOffset, host_cpOffsetV); - - Kokkos::View knotsV("knots", knotsI.size()); - auto host_knotsV = Kokkos::create_mirror_view(knotsV); - for (int i = 0; i < knotsI.size(); i++) { - host_knotsV(i) = knotsI[i]; - } - knots = knotsV; - Kokkos::deep_copy(knots, host_knotsV); - - Kokkos::View knotsOffsetV("knotsOffset", 1); - auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); - host_knotsOffsetV(0) = knotsI.size(); - knotsOffset = knotsOffsetV; - Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); - - //TO DO: Implement 1st&2nd Coef function - calculateDerivCoeff(); + Kokkos::View orderV("Orders", 1); + auto host_orderV = Kokkos::create_mirror_view(orderV); + host_orderV(0) = order_p; + order = orderV; + Kokkos::deep_copy(order, host_orderV); + + Kokkos::View ctrlPtsV("ctrlPts", ctrlPts_x.size()); + auto host_ctrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); + for (int i = 0; i < ctrlPts_x.size(); i++) { + host_ctrlPtsV(i, 0) = ctrlPts_x[i]; + host_ctrlPtsV(i, 1) = ctrlPts_y[i]; + } + ctrlPts = ctrlPtsV; + Kokkos::deep_copy(ctrlPts, host_ctrlPtsV); + + Kokkos::View cpOffsetV("cpOffset", 1); + auto host_cpOffsetV = Kokkos::create_mirror_view(cpOffsetV); + host_cpOffsetV(0) = ctrlPts_x.size(); + host_cpOffsetV(0) = ctrlPts_x.size(); + + cpOffset = cpOffsetV; + Kokkos::deep_copy(cpOffset, host_cpOffsetV); + + Kokkos::View knotsV("knots", knotsI.size()); + auto host_knotsV = Kokkos::create_mirror_view(knotsV); + for (int i = 0; i < knotsI.size(); i++) { + host_knotsV(i) = knotsI[i]; + } + knots = knotsV; + Kokkos::deep_copy(knots, host_knotsV); + + Kokkos::View knotsOffsetV("knotsOffset", 1); + auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); + host_knotsOffsetV(0) = knotsI.size(); + knotsOffset = knotsOffsetV; + Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); + + //TO DO: Implement 1st&2nd Coef function + calculateDerivCoeff(); } BSplineKokkos2D(std::vector& multiSplines) { //Loop over all the splines to know how much space to allocate - int orderSize = 0; - int ctrlPtsSize = 0; - int cpOffsetSize = 0; - int knotSize = 0; - int knotsOffsetSize = 0; - - for (int i = 0; i < multiSplines.size(); i++) { - orderSize += multiSplines[i].getOrder().extent(0); - ctrlPtsSize += multiSplines[i].getCtrlPts().extent(0); - cpOffsetSize += multiSplines[i].getCPOffset().extent(0); - knotSize += multiSplines[i].getKnots().extent(0); - knotsOffsetSize += multiSplines[i].getKnotsOffset().extent(0); - } - - //Populate the views - Kokkos::View orderV ("order", orderSize); - Kokkos::View ctrlPtsV("ctrlPts", ctrlPtsSize); - Kokkos::View cPOffsetV("ctrlPtsOffset", cpOffsetSize); - Kokkos::View knotsV("knots", knotSize); - Kokkos::View knotsOffsetV("knotsOffset", knotsOffsetSize); - - //Create the mirror view on host to move the data over - auto mvOrderV = Kokkos::create_mirror_view(orderV); - auto mvCtrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); - auto mvCPOffsetV = Kokkos::create_mirror_view(cPOffsetV); - auto mvKnotsV = Kokkos::create_mirror_view(knotsV); - auto mvKnotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); - //Copy the data over - int oidx = 0; - int cPidx = 0; - int cOidx = 0; - int kidx = 0; - int kOidx = 0; - for (int i = 0; i < multiSplines.size(); i++) { - //Populate orders - Kokkos::View intView = multiSplines[i].getOrder(); - auto mvIntView = Kokkos::create_mirror_view(intView); - Kokkos::deep_copy(mvIntView, intView); - for (int j = 0; j < intView.extent(0); j++) { - mvOrderV(oidx+j) = mvIntView(j); - } - oidx += mvIntView.extent(0); - - //Populate ctrlPts - Kokkos::View double2DView = multiSplines[i].getCtrlPts(); - auto mvDouble2DView = Kokkos::create_mirror_view(double2DView); - Kokkos::deep_copy(mvDouble2DView, double2DView); - for (int j = 0; j < mvDouble2DView.extent(0); j++) { - mvCtrlPtsV(cPidx+j, 0) = mvDouble2DView(j, 0); - mvCtrlPtsV(cPidx+j, 1) = mvDouble2DView(j, 1); - } - cPidx += mvDouble2DView.extent(0); - - //Populate ctrlPtsOffset - intView = multiSplines[i].getCPOffset(); - mvIntView = Kokkos::create_mirror_view(intView); - Kokkos::deep_copy(mvIntView, intView); - - for (int j = 0; j < intView.extent(0); j++) { - mvCPOffsetV(cOidx + j) = intView(j); - } - cOidx += intView.extent(0); - - //Populate knots - Kokkos::View doubleView = multiSplines[i].getKnots(); - auto mvDoubleView = Kokkos::create_mirror_view(doubleView); - Kokkos::deep_copy(mvDoubleView, doubleView); - - for (int j = 0; j < doubleView.extent(0); j++) { - mvKnotsV(kidx+j) = doubleView(j); - } - kidx += doubleView.extent(0); - - //Populate knots offset - intView = multiSplines[i].getKnotsOffset(); - mvIntView = Kokkos::create_mirror_view(intView); - Kokkos::deep_copy(mvIntView, intView); - - for (int j = 0; j < intView.extent(0); j++) { - mvKnotsOffsetV(kOidx+j) = mvIntView(j); - } - kOidx += mvIntView.extent(0); - } - - //Copy the data on host to device - order = orderV; - ctrlPts = ctrlPtsV; - cpOffset = cPOffsetV; - knots = knotsV; - knotsOffset = knotsOffsetV; - - Kokkos::deep_copy(order, mvOrderV); - Kokkos::deep_copy(ctrlPts, mvCtrlPtsV); - Kokkos::deep_copy(cpOffset, mvCPOffsetV); - Kokkos::deep_copy(knots, mvKnotsV); - Kokkos::deep_copy(knotsOffset, mvKnotsOffsetV); - - //TO DO: Implement 1st&2nd Coef function - calculateDerivCoeff(); + int orderSize = 0; + int ctrlPtsSize = 0; + int cpOffsetSize = 0; + int knotSize = 0; + int knotsOffsetSize = 0; + + for (int i = 0; i < multiSplines.size(); i++) { + orderSize += multiSplines[i].getOrder().extent(0); + ctrlPtsSize += multiSplines[i].getCtrlPts().extent(0); + cpOffsetSize += multiSplines[i].getCPOffset().extent(0); + knotSize += multiSplines[i].getKnots().extent(0); + knotsOffsetSize += multiSplines[i].getKnotsOffset().extent(0); + } + + //Populate the views + Kokkos::View orderV ("order", orderSize); + Kokkos::View ctrlPtsV("ctrlPts", ctrlPtsSize); + Kokkos::View cPOffsetV("ctrlPtsOffset", cpOffsetSize); + Kokkos::View knotsV("knots", knotSize); + Kokkos::View knotsOffsetV("knotsOffset", knotsOffsetSize); + + //Create the mirror view on host to move the data over + auto mvOrderV = Kokkos::create_mirror_view(orderV); + auto mvCtrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); + auto mvCPOffsetV = Kokkos::create_mirror_view(cPOffsetV); + auto mvKnotsV = Kokkos::create_mirror_view(knotsV); + auto mvKnotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); + //Copy the data over + int oidx = 0; + int cPidx = 0; + int cOidx = 0; + int kidx = 0; + int kOidx = 0; + for (int i = 0; i < multiSplines.size(); i++) { + //Populate orders + Kokkos::View intView = multiSplines[i].getOrder(); + auto mvIntView = Kokkos::create_mirror_view(intView); + Kokkos::deep_copy(mvIntView, intView); + for (int j = 0; j < intView.extent(0); j++) { + mvOrderV(oidx+j) = mvIntView(j); + } + oidx += mvIntView.extent(0); + + //Populate ctrlPts + Kokkos::View double2DView = multiSplines[i].getCtrlPts(); + auto mvDouble2DView = Kokkos::create_mirror_view(double2DView); + Kokkos::deep_copy(mvDouble2DView, double2DView); + for (int j = 0; j < mvDouble2DView.extent(0); j++) { + mvCtrlPtsV(cPidx+j, 0) = mvDouble2DView(j, 0); + mvCtrlPtsV(cPidx+j, 1) = mvDouble2DView(j, 1); + } + cPidx += mvDouble2DView.extent(0); + + //Populate ctrlPtsOffset + intView = multiSplines[i].getCPOffset(); + mvIntView = Kokkos::create_mirror_view(intView); + Kokkos::deep_copy(mvIntView, intView); + + for (int j = 0; j < intView.extent(0); j++) { + mvCPOffsetV(cOidx + j) = intView(j); + } + cOidx += intView.extent(0); + + //Populate knots + Kokkos::View doubleView = multiSplines[i].getKnots(); + auto mvDoubleView = Kokkos::create_mirror_view(doubleView); + Kokkos::deep_copy(mvDoubleView, doubleView); + + for (int j = 0; j < doubleView.extent(0); j++) { + mvKnotsV(kidx+j) = doubleView(j); + } + kidx += doubleView.extent(0); + + //Populate knots offset + intView = multiSplines[i].getKnotsOffset(); + mvIntView = Kokkos::create_mirror_view(intView); + Kokkos::deep_copy(mvIntView, intView); + + for (int j = 0; j < intView.extent(0); j++) { + mvKnotsOffsetV(kOidx+j) = mvIntView(j); + } + kOidx += mvIntView.extent(0); + } + + //Copy the data on host to device + order = orderV; + ctrlPts = ctrlPtsV; + cpOffset = cPOffsetV; + knots = knotsV; + knotsOffset = knotsOffsetV; + + Kokkos::deep_copy(order, mvOrderV); + Kokkos::deep_copy(ctrlPts, mvCtrlPtsV); + Kokkos::deep_copy(cpOffset, mvCPOffsetV); + Kokkos::deep_copy(knots, mvKnotsV); + Kokkos::deep_copy(knotsOffset, mvKnotsOffsetV); + + //TO DO: Implement 1st&2nd Coef function + calculateDerivCoeff(); } void calculateDerivCoeff() { //Allocate the views we need - Kokkos::View ctrlPts1stDV("ctrlPts1stDeriv", ctrlPts.extent(0)-cpOffset.extent(0)); - Kokkos::View cP1stDOffsetV("cP1stDOffset", cpOffset.extent(0)); - Kokkos::View cP2ndDOffsetV("cP2ndDOffset", cpOffset.extent(0)); + Kokkos::View ctrlPts1stDV("ctrlPts1stDeriv", ctrlPts.extent(0)-cpOffset.extent(0)); + Kokkos::View cP1stDOffsetV("cP1stDOffset", cpOffset.extent(0)); + Kokkos::View cP2ndDOffsetV("cP2ndDOffset", cpOffset.extent(0)); + + //Set up the offset views + auto mvCP1stDOffsetV = Kokkos::create_mirror_view(cP1stDOffsetV); + auto mvCP2ndDOffsetV = Kokkos::create_mirror_view(cP2ndDOffsetV); - //Set up the offset views - auto mvCP1stDOffsetV = Kokkos::create_mirror_view(cP1stDOffsetV); - auto mvCP2ndDOffsetV = Kokkos::create_mirror_view(cP2ndDOffsetV); - - auto mvCPOffset = Kokkos::create_mirror_view(cpOffset); + auto mvCPOffset = Kokkos::create_mirror_view(cpOffset); + + if (mvCPOffset.extent(0) > 1) { + Kokkos::deep_copy(mvCPOffset, cpOffset); + for (int i = 1; i < mvCPOffset.extent(0); i++) { + mvCP1stDOffsetV(i) = mvCPOffset(i)-1; + mvCP2ndDOffsetV(i) = mvCPOffset(i)-2; + } + } + else { + mvCP1stDOffsetV(0) = mvCPOffset(0)-1; + mvCP2ndDOffsetV(0) = mvCPOffset(0)-2; + } - if (mvCPOffset.extent(0) > 1) { - Kokkos::deep_copy(mvCPOffset, cpOffset); - for (int i = 1; i < mvCPOffset.extent(0); i++) { - mvCP1stDOffsetV(i) = mvCPOffset(i)-1; - mvCP2ndDOffsetV(i) = mvCPOffset(i)-2; - } - } - else { - mvCP1stDOffsetV(0) = mvCPOffset(0)-1; - mvCP2ndDOffsetV(0) = mvCPOffset(0)-2; - } - - auto mvOrder = Kokkos::create_mirror_view(order); - auto mvKnots = Kokkos::create_mirror_view(knots); - auto mvCtrlPts = Kokkos::create_mirror_view(ctrlPts); - auto mvCtrlPts1stDV = Kokkos::create_mirror_view(ctrlPts1stDV); - Kokkos::deep_copy(mvOrder, order); - Kokkos::deep_copy(mvKnots, knots); - Kokkos::deep_copy(mvCtrlPts, ctrlPts); - - //Calculate 1st derivative coef - int offidx = 0; //Offset index - int oidx = 0; //Order index - for (int i = 1; i < mvCtrlPts1stDV.extent(0)+1; i++) { - if (i == mvCP1stDOffsetV(offidx)+1) { - oidx++; - offidx++; - continue; - } - //We need to check whether we are on the border for the next spline in our structure - double delta = double(mvOrder(oidx)-1) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i)); - - mvCtrlPts1stDV(i-1, 0) = (mvCtrlPts(i, 0) - mvCtrlPts(i-1, 0))*delta; - mvCtrlPts1stDV(i-1, 1) = (mvCtrlPts(i, 1) - mvCtrlPts(i-1, 1))*delta; - } - - //Calculate 2nd derivative coef - Kokkos::View ctrlPts2ndDV("ctrlPts2ndDeriv", ctrlPts.extent(0)-(2*cpOffset.extent(0))); - auto mvCtrlPts2ndDV = Kokkos::create_mirror_view(ctrlPts2ndDV); - - offidx = 0; - oidx = 0; - for (int i = 1; i < ctrlPts1stDV.extent(0); i++) { - if (i == mvCP2ndDOffsetV(offidx)+2) { - oidx++; - offidx++; - continue; - } - double delta = double(mvOrder(oidx)-2) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i+1)); - - mvCtrlPts2ndDV(i-1, 0) = (mvCtrlPts1stDV(i, 0) - mvCtrlPts1stDV(i-1, 0)) * delta; - mvCtrlPts2ndDV(i-1, 1) = (mvCtrlPts1stDV(i, 1) - mvCtrlPts1stDV(i-1, 1)) * delta; - } - - //Copy to device - Kokkos::deep_copy(cP1stDOffsetV, mvCP1stDOffsetV); - Kokkos::deep_copy(cP2ndDOffsetV, mvCP2ndDOffsetV); - Kokkos::deep_copy(ctrlPts1stDV, mvCtrlPts1stDV); - Kokkos::deep_copy(ctrlPts2ndDV, mvCtrlPts2ndDV); - - cp1stDOffset = cP1stDOffsetV; - cp2ndDOffset = cP2ndDOffsetV; - ctrlPts1stD = ctrlPts1stDV; - ctrlPts2ndD = ctrlPts2ndDV; - - + auto mvOrder = Kokkos::create_mirror_view(order); + auto mvKnots = Kokkos::create_mirror_view(knots); + auto mvCtrlPts = Kokkos::create_mirror_view(ctrlPts); + auto mvCtrlPts1stDV = Kokkos::create_mirror_view(ctrlPts1stDV); + Kokkos::deep_copy(mvOrder, order); + Kokkos::deep_copy(mvKnots, knots); + Kokkos::deep_copy(mvCtrlPts, ctrlPts); + + //Calculate 1st derivative coef + int offidx = 0; //Offset index + int oidx = 0; //Order index + for (int i = 1; i < mvCtrlPts1stDV.extent(0)+1; i++) { + if (i == mvCP1stDOffsetV(offidx)+1) { + oidx++; + offidx++; + continue; + } + //We need to check whether we are on the border for the next spline in our structure + double delta = double(mvOrder(oidx)-1) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i)); + + mvCtrlPts1stDV(i-1, 0) = (mvCtrlPts(i, 0) - mvCtrlPts(i-1, 0))*delta; + mvCtrlPts1stDV(i-1, 1) = (mvCtrlPts(i, 1) - mvCtrlPts(i-1, 1))*delta; + } + + //Calculate 2nd derivative coef + Kokkos::View ctrlPts2ndDV("ctrlPts2ndDeriv", ctrlPts.extent(0)-(2*cpOffset.extent(0))); + auto mvCtrlPts2ndDV = Kokkos::create_mirror_view(ctrlPts2ndDV); + + offidx = 0; + oidx = 0; + for (int i = 1; i < ctrlPts1stDV.extent(0); i++) { + if (i == mvCP2ndDOffsetV(offidx)+2) { + oidx++; + offidx++; + continue; + } + double delta = double(mvOrder(oidx)-2) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i+1)); + + mvCtrlPts2ndDV(i-1, 0) = (mvCtrlPts1stDV(i, 0) - mvCtrlPts1stDV(i-1, 0)) * delta; + mvCtrlPts2ndDV(i-1, 1) = (mvCtrlPts1stDV(i, 1) - mvCtrlPts1stDV(i-1, 1)) * delta; + } + + //Copy to device + Kokkos::deep_copy(cP1stDOffsetV, mvCP1stDOffsetV); + Kokkos::deep_copy(cP2ndDOffsetV, mvCP2ndDOffsetV); + Kokkos::deep_copy(ctrlPts1stDV, mvCtrlPts1stDV); + Kokkos::deep_copy(ctrlPts2ndDV, mvCtrlPts2ndDV); + + cp1stDOffset = cP1stDOffsetV; + cp2ndDOffset = cP2ndDOffsetV; + ctrlPts1stD = ctrlPts1stDV; + ctrlPts2ndD = ctrlPts2ndDV; } KOKKOS_FUNCTION void evalDeBoor(double x, int splineo, int lKnot, Kokkos::View result, const Kokkos::View order, const Kokkos::View knots, const Kokkos::View ctrlPts_1stD) const { - //DeBoor's algorithm for BSpline 1st deriv calculation - int order_t = lKnot; - int leftPt = 0; - - while (x > knots(lKnot+1)) { - lKnot++; - leftPt++; - } - - //Allocate temporary points - double ptsX[3]; - double ptsY[3]; - - int idx = 0; - for (int i = leftPt; i < leftPt + order_t; i++) { - ptsX[idx] = ctrlPts_1stD(i, 0); - ptsY[idx] = ctrlPts_1stD(i, 1); - idx++; - } - - auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order_t+2, lKnot+order_t)); - - //Calculation loop - for (int r = 1; r <= order_t; r++) { - for(int i = order_t-1; i >= r; i--) { - double alpha; - if (localKnots(i-1) - localKnots(i+order_t-r-1) > 1e-12) { - alpha = 0; + //DeBoor's algorithm for BSpline 1st deriv calculation + int order_t = lKnot; + int leftPt = 0; + + while (x > knots(lKnot+1)) { + lKnot++; + leftPt++; + } + + //Allocate temporary points + double ptsX[3]; + double ptsY[3]; + + int idx = 0; + for (int i = leftPt; i < leftPt + order_t; i++) { + ptsX[idx] = ctrlPts_1stD(i, 0); + ptsY[idx] = ctrlPts_1stD(i, 1); + idx++; } - else { - alpha = (x - localKnots(i-1)) / (knots(i+order_t-r-1) - knots(i-1)); + + auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order_t+2, lKnot+order_t)); + + //Calculation loop + for (int r = 1; r <= order_t; r++) { + for(int i = order_t-1; i >= r; i--) { + double alpha; + if (localKnots(i-1) - localKnots(i+order_t-r-1) > 1e-12) { + alpha = 0; + } + else { + alpha = (x - localKnots(i-1)) / (knots(i+order_t-r-1) - knots(i-1)); + } + ptsX[i] = (1. - alpha) * ptsX[i-1]+alpha * ptsX[i]; + ptsY[i] = (1. - alpha) * ptsY[i-1]+alpha * ptsY[i]; + } + + result(0) = ptsX[order_t-1]; + result(1) = ptsY[order_t-1]; } - ptsX[i] = (1. - alpha) * ptsX[i-1]+alpha * ptsX[i]; - ptsY[i] = (1. - alpha) * ptsY[i-1]+alpha * ptsY[i]; - } - - result(0) = ptsX[order_t-1]; - result(1) = ptsY[order_t-1]; - } } Kokkos::View eval1stDeriv(Kokkos::View xVals, int splineo) const { - int lKnot; - Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); - lKnot--; - Kokkos::View res("result", 2); - Kokkos::parallel_for("parallel evalDeBoors", xVals.size(), KOKKOS_CLASS_LAMBDA(int i){ - evalDeBoor(xVals(i), splineo, lKnot, res, order, knots, ctrlPts1stD); - v}); - return res; + int lKnot; + Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); + lKnot--; + Kokkos::View res("result", 2); + Kokkos::parallel_for("parallel evalDeBoors", xVals.size(), KOKKOS_CLASS_LAMBDA(int i){ + evalDeBoor(xVals(i), splineo, lKnot, res, order, knots, ctrlPts1stD); + v}); + return res; } //Second derivative calculation KOKKOS_FUNCTION void evalDeBoor2(double x, int splineo, int lKnot, Kokkos::View result, const Kokkos::View order, const Kokkos::View knots, const Kokkos::View ctrlPts_2ndD) const { - if (order(splineo) == 2) { - result(0) = 0; - result(1) = 0; - return; - } - - int order_t = lKnot-1; - int leftPt = 0; - - while (knots(lKnot+1) < x) { - lKnot++; - leftPt++; - } - - double ptsX[3]; - double ptsY[3]; - - int idx = 0; - for (int i = leftPt; i < leftPt+order_t; i++) { - ptsX[idx] = ctrlPts_2ndD(i, 0); - ptsY[idx] = ctrlPts_2ndD(i, 1); - idx++; - } - - auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order_t+2, lKnot+order_t)); - - for (int r = 1; r <= order_t; r++) { - for (int i = order_t-1; i >= r; i--) { - double aLeft = localKnots(i-1); - double aRight = localKnots(i+order_t-r-1); - double alpha; - if (aLeft == aRight) { - alpha = 0.; + if (order(splineo) == 2) { + result(0) = 0; + result(1) = 0; + return; } - else { - alpha = (x - aLeft) / (aRight - aLeft); + + int order_t = lKnot-1; + int leftPt = 0; + + while (knots(lKnot+1) < x) { + lKnot++; + leftPt++; } - - ptsX[i] = (1. - alpha) * ptsX[i-1] + alpha * ptsX[i]; - ptsY[i] = (1. - alpha) * ptsY[i-1] + alpha * ptsY[i]; + + double ptsX[3]; + double ptsY[3]; + + int idx = 0; + for (int i = leftPt; i < leftPt+order_t; i++) { + ptsX[idx] = ctrlPts_2ndD(i, 0); + ptsY[idx] = ctrlPts_2ndD(i, 1); + idx++; + } + + auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order_t+2, lKnot+order_t)); + + for (int r = 1; r <= order_t; r++) { + for (int i = order_t-1; i >= r; i--) { + double aLeft = localKnots(i-1); + double aRight = localKnots(i+order_t-r-1); + double alpha; + if (aLeft == aRight) { + alpha = 0.; + } + else { + alpha = (x - aLeft) / (aRight - aLeft); + } + + ptsX[i] = (1. - alpha) * ptsX[i-1] + alpha * ptsX[i]; + ptsY[i] = (1. - alpha) * ptsY[i-1] + alpha * ptsY[i]; + } + } + + result(0) = ptsX[order_t-1]; + result(1) = ptsY[order_t-1]; + } - } - - result(0) = ptsX[order_t-1]; - result(1) = ptsY[order_t-1]; - - } - - Kokkos::View eval2ndDeriv(Kokkos::View xVals, int splineo) const { - int lKnot; - Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); - lKnot--; - Kokkos::View res("result", 2); - Kokkos::parallel_for("parallel evalDeBoors 2", xVals.size(), KOKKOS_CLASS_LAMBDA(int i) { - evalDeBoor2(xVals(i), splineo, lKnot, res, order, knots, ctrlPts2ndD); - }); - return res; + + Kokkos::View eval2ndDeriv(Kokkos::View xVals, int splineo) const { + int lKnot; + Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); + lKnot--; + Kokkos::View res("result", 2); + Kokkos::parallel_for("parallel evalDeBoors 2", xVals.size(), KOKKOS_CLASS_LAMBDA(int i) { + evalDeBoor2(xVals(i), splineo, lKnot, res, order, knots, ctrlPts2ndD); + }); + return res; } From 00a549b8e1c6123df325970f784bad643bb09081 Mon Sep 17 00:00:00 2001 From: hsiehhRPI <112642746+hsiehhRPI@users.noreply.github.com> Date: Mon, 4 May 2026 13:52:37 -0400 Subject: [PATCH 69/73] Update testSplineKokkos2DBase.cpp Fix indentation for the nested loops --- testSplineKokkos2DBase.cpp | 216 ++++++++++++++++++------------------- 1 file changed, 105 insertions(+), 111 deletions(-) diff --git a/testSplineKokkos2DBase.cpp b/testSplineKokkos2DBase.cpp index ccf97d5..c42d30b 100644 --- a/testSplineKokkos2DBase.cpp +++ b/testSplineKokkos2DBase.cpp @@ -24,9 +24,9 @@ int main(int argc, char* argv[]) { int retVal = 0; if (argc != 3) { std::cerr<< "Input arguments: " << std::endl; - std::cerr << "input csv need these columns: "; - std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; - return 1; + std::cerr << "input csv need these columns: "; + std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; + return 1; } Kokkos::initialize(argc, argv); { @@ -38,116 +38,110 @@ int main(int argc, char* argv[]) { #define MemSpace Kokkos::HostSpace #endif - using ExecutionSpace = MemSpace::execution_space; - - std::string inputCSV = argv[1]; - int extensionPos = inputCSV.rfind("."); - int slashPos = inputCSV.rfind("/"); - std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); - double expectedCurveLength = std::stod(argv[2]); - auto curve = CurveReader::readCurveInfo(inputCSV); - - //Construct BSpline2d object - SplineInterp::BSpline2d serialBSP; - if (curve.x.size() == 2) { - serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); - } else { - serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); - } - - std::vector ctrlPtsX, ctrlPtsY, knots, weight; - int order; - - serialBSP.x.getpara(order, ctrlPtsX, knots, weight); - serialBSP.y.getpara(order, ctrlPtsY, knots, weight); - - BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); - - auto intView = Kokkos::create_mirror_view(kokkosBSP.getOrder()); - Kokkos::deep_copy(intView, kokkosBSP.getOrder()); - //Testing the order initialization - double diff = std::fabs(order - intView(0)); - if (diff > EPSILON) { - std::cout << "Order difference : " << diff << std::endl; - std::cout << "Serial: " << order << " Kokkos: " << intView(0) << std::endl; - retVal = 1; - } - - auto double2DView = Kokkos::create_mirror_view(kokkosBSP.getCtrlPts()); - Kokkos::deep_copy(double2DView, kokkosBSP.getCtrlPts()); - - //Testing ctrlPts initialization - double xDiff, yDiff; - for (int i = 0; i < ctrlPtsX.size(); i++) { - xDiff = std::fabs(ctrlPtsX[i] - double2DView(i, 0)); - yDiff = std::fabs(ctrlPtsY[i] - double2DView(i, 1)); - if (xDiff > EPSILON || yDiff > EPSILON) { - std::cout << "CtrlPts difference: x = " << xDiff << " y = " << yDiff << std::endl; - std::cout << "Serial: " << ctrlPtsX[i] << ", " << ctrlPtsY[i] << std::endl; - std::cout << "Kokkos: " << double2DView(i, 0) << ", " << double2DView(i, 1) << std::endl; - retVal = 1; - } - } - - //Test knots initialization - auto doubleView = Kokkos::create_mirror_view(kokkosBSP.getKnots()); - Kokkos::deep_copy(doubleView, kokkosBSP.getKnots()); - for (int i = 0; i < knots.size(); i++) { - diff = std::fabs(knots[i] - doubleView(i)); - if (diff > EPSILON) { - std::cout << "Knots difference: " << diff << std::endl; - std::cout << "Serial: " << knots[i] << std::endl; - std::cout << "Kokkos: " << doubleView(i) << std::endl; - retVal = 1; - } - } - - //Test 1st deriv coef initialization - Kokkos::View coef ("getCPCoe2", kokkosBSP.getCP1stD().extent(0)); - - coef = kokkosBSP.getCP1stD(); - - auto mv_coef = Kokkos::create_mirror_view(coef); - - Kokkos::deep_copy(mv_coef, coef); - - std::vector serialCoefX = serialBSP.x.getCtrlPts_1st(); - std::vector serialCoefY = serialBSP.y.getCtrlPts_1st(); - - for (int i = 0; i < serialCoefX.size(); i++) { - double diffX = std::fabs(serialCoefX[i] - mv_coef(i, 0)); - double diffY = std::fabs(serialCoefY[i] - mv_coef(i, 1)); - if (diffX > EPSILON || diffY > EPSILON) { - std::cout << "diffX: " << diffX << std::endl; - std::cout << "diffY: " << diffY << std::endl; - std::cout << "Serial 1st coef: " << serialCoefX[i] << ", " << serialCoefY[i] << std::endl; - std::cout << "Kokkos 1st coef: " << mv_coef(i, 0)<< ", " << mv_coef(i, 1) << std::endl; - retVal = 1; + using ExecutionSpace = MemSpace::execution_space; + + std::string inputCSV = argv[1]; + int extensionPos = inputCSV.rfind("."); + int slashPos = inputCSV.rfind("/"); + std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); + double expectedCurveLength = std::stod(argv[2]); + auto curve = CurveReader::readCurveInfo(inputCSV); + + //Construct BSpline2d object + SplineInterp::BSpline2d serialBSP; + if (curve.x.size() == 2) { + serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); + } else { + serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); } - } - - Kokkos::Viewcoef2 ("getCPCoe2", kokkosBSP.getCP2ndD().extent(0)); - coef2 = kokkosBSP.getCP2ndD(); - - mv_coef = Kokkos::create_mirror_view(coef2); - - Kokkos::deep_copy(mv_coef, coef2); - - serialCoefX = serialBSP.x.getCtrlPts_2nd(); - serialCoefY = serialBSP.y.getCtrlPts_2nd(); - for (int i = 0; i < serialCoefX.size(); i++) { - double diffX = std::fabs(serialCoefX[i] - mv_coef(i, 0)); - double diffY = std::fabs(serialCoefY[i] - mv_coef(i, 1)); - if (diffX > EPSILON || diffY > EPSILON) { - std::cout << "diffX: " << diffX << std::endl; - std::cout << "diffY: " << diffY << std::endl; - std::cout << "Serial 2nd coef: " << serialCoefX[i] << ", " << serialCoefY[i] << std::endl; - std::cout << "Kokkos 2nd coef: " << mv_coef(i, 0)<< ", " << mv_coef(i, 1) << std::endl; - retVal = 1; - } - } - + std::vector ctrlPtsX, ctrlPtsY, knots, weight; + int order; + + serialBSP.x.getpara(order, ctrlPtsX, knots, weight); + serialBSP.y.getpara(order, ctrlPtsY, knots, weight); + + BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); + + auto intView = Kokkos::create_mirror_view(kokkosBSP.getOrder()); + Kokkos::deep_copy(intView, kokkosBSP.getOrder()); + //Testing the order initialization + double diff = std::fabs(order - intView(0)); + if (diff > EPSILON) { + std::cout << "Order difference : " << diff << std::endl; + std::cout << "Serial: " << order << " Kokkos: " << intView(0) << std::endl; + retVal = 1; + } + + auto double2DView = Kokkos::create_mirror_view(kokkosBSP.getCtrlPts()); + Kokkos::deep_copy(double2DView, kokkosBSP.getCtrlPts()); + + //Testing ctrlPts initialization + double xDiff, yDiff; + for (int i = 0; i < ctrlPtsX.size(); i++) { + xDiff = std::fabs(ctrlPtsX[i] - double2DView(i, 0)); + yDiff = std::fabs(ctrlPtsY[i] - double2DView(i, 1)); + if (xDiff > EPSILON || yDiff > EPSILON) { + std::cout << "CtrlPts difference: x = " << xDiff << " y = " << yDiff << std::endl; + std::cout << "Serial: " << ctrlPtsX[i] << ", " << ctrlPtsY[i] << std::endl; + std::cout << "Kokkos: " << double2DView(i, 0) << ", " << double2DView(i, 1) << std::endl; + retVal = 1; + } + } + + //Test knots initialization + auto doubleView = Kokkos::create_mirror_view(kokkosBSP.getKnots()); + Kokkos::deep_copy(doubleView, kokkosBSP.getKnots()); + for (int i = 0; i < knots.size(); i++) { + diff = std::fabs(knots[i] - doubleView(i)); + if (diff > EPSILON) { + std::cout << "Knots difference: " << diff << std::endl; + std::cout << "Serial: " << knots[i] << std::endl; + std::cout << "Kokkos: " << doubleView(i) << std::endl; + retVal = 1; + } + } + + //Test 1st deriv coef initialization + Kokkos::View coef ("getCPCoe2", kokkosBSP.getCP1stD().extent(0)); + coef = kokkosBSP.getCP1stD(); + auto mv_coef = Kokkos::create_mirror_view(coef); + Kokkos::deep_copy(mv_coef, coef); + std::vector serialCoefX = serialBSP.x.getCtrlPts_1st(); + std::vector serialCoefY = serialBSP.y.getCtrlPts_1st(); + + for (int i = 0; i < serialCoefX.size(); i++) { + double diffX = std::fabs(serialCoefX[i] - mv_coef(i, 0)); + double diffY = std::fabs(serialCoefY[i] - mv_coef(i, 1)); + if (diffX > EPSILON || diffY > EPSILON) { + std::cout << "diffX: " << diffX << std::endl; + std::cout << "diffY: " << diffY << std::endl; + std::cout << "Serial 1st coef: " << serialCoefX[i] << ", " << serialCoefY[i] << std::endl; + std::cout << "Kokkos 1st coef: " << mv_coef(i, 0)<< ", " << mv_coef(i, 1) << std::endl; + retVal = 1; + } + + } + + Kokkos::Viewcoef2 ("getCPCoe2", kokkosBSP.getCP2ndD().extent(0)); + coef2 = kokkosBSP.getCP2ndD(); + mv_coef = Kokkos::create_mirror_view(coef2); + + Kokkos::deep_copy(mv_coef, coef2); + + serialCoefX = serialBSP.x.getCtrlPts_2nd(); + serialCoefY = serialBSP.y.getCtrlPts_2nd(); + for (int i = 0; i < serialCoefX.size(); i++) { + double diffX = std::fabs(serialCoefX[i] - mv_coef(i, 0)); + double diffY = std::fabs(serialCoefY[i] - mv_coef(i, 1)); + if (diffX > EPSILON || diffY > EPSILON) { + std::cout << "diffX: " << diffX << std::endl; + std::cout << "diffY: " << diffY << std::endl; + std::cout << "Serial 2nd coef: " << serialCoefX[i] << ", " << serialCoefY[i] << std::endl; + std::cout << "Kokkos 2nd coef: " << mv_coef(i, 0)<< ", " << mv_coef(i, 1) << std::endl; + retVal = 1; + } + } } Kokkos::finalize(); return retVal; From df866730e9db0573de1d59e5f315beaee307e0c1 Mon Sep 17 00:00:00 2001 From: hsiehhRPI <112642746+hsiehhRPI@users.noreply.github.com> Date: Mon, 4 May 2026 13:54:06 -0400 Subject: [PATCH 70/73] Update testKokkos2D1stDeriv.cpp Indentation fix --- testKokkos2D1stDeriv.cpp | 74 ++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/testKokkos2D1stDeriv.cpp b/testKokkos2D1stDeriv.cpp index d1f98f7..30b66bd 100644 --- a/testKokkos2D1stDeriv.cpp +++ b/testKokkos2D1stDeriv.cpp @@ -25,7 +25,7 @@ int main(int argc, char* argv[]) { Kokkos::initialize(argc, argv); { - #ifdef KOKKOS_ENABLE_CUDA + #ifdef KOKKOS_ENABLE_CUDA #define MemSpace Kokkos::CudaSpace #endif #ifndef MemSpace @@ -34,7 +34,7 @@ int main(int argc, char* argv[]) { using ExecutionSpace = MemSpace::execution_space; - std::string inputCSV = argv[1]; + std::string inputCSV = argv[1]; int extensionPos = inputCSV.rfind("."); int slashPos = inputCSV.rfind("/"); std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); @@ -49,41 +49,41 @@ int main(int argc, char* argv[]) { serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); } - std::vector ctrlPtsX, ctrlPtsY, knots, weight; - int order; - - //Get the info from serial spline, we will feed this to kokkos spline - serialBSP.x.getpara(order, ctrlPtsX, knots, weight); - serialBSP.y.getpara(order, ctrlPtsY, knots, weight); - - BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); - - std::vector evalAt = {0, 0.2, 0.41, 0.5, 0.66, 0.73, 0.75, 0.89, 0.94, 1}; - for (int i = 0; i < 10; i++) { - double derivX = serialBSP.x.evalFirstDeriv(evalAt[i]); - double derivY = serialBSP.y.evalFirstDeriv(evalAt[i]); - - Kokkos::View res("deriv result", 2); - Kokkos::View xVals ("paraCoor", 1); - auto mvXVals = Kokkos::create_mirror_view(xVals); - mvXVals(0) = evalAt[i]; - Kokkos::deep_copy(xVals, mvXVals); - - res = kokkosBSP.eval1stDeriv(xVals, 0); - - auto mvRes = Kokkos::create_mirror_view(res); - Kokkos::deep_copy(mvRes, res); - - double xDiff = std::fabs(derivX) - std::fabs(mvRes(0)); - double yDiff = std::fabs(derivY) - std::fabs(mvRes(1)); - if (xDiff > EPSILON || yDiff > EPSILON) { - std::cout << "Test " << i+1 << " failed, eval at: " << evalAt[i] << std::endl; - std::cout << "Difference: x = " << xDiff << " y = " << yDiff << std::endl; - std::cout << "SERIAL 1st deriv: x = " << derivX << " y = " << derivY << std::endl; - std::cout << "KOKKOS 1st deriv: x = " << mvRes(0) << " y = " << mvRes(1) << std::endl; - retVal = 1; - } - } + std::vector ctrlPtsX, ctrlPtsY, knots, weight; + int order; + + //Get the info from serial spline, we will feed this to kokkos spline + serialBSP.x.getpara(order, ctrlPtsX, knots, weight); + serialBSP.y.getpara(order, ctrlPtsY, knots, weight); + + BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); + + std::vector evalAt = {0, 0.2, 0.41, 0.5, 0.66, 0.73, 0.75, 0.89, 0.94, 1}; + for (int i = 0; i < 10; i++) { + double derivX = serialBSP.x.evalFirstDeriv(evalAt[i]); + double derivY = serialBSP.y.evalFirstDeriv(evalAt[i]); + + Kokkos::View res("deriv result", 2); + Kokkos::View xVals ("paraCoor", 1); + auto mvXVals = Kokkos::create_mirror_view(xVals); + mvXVals(0) = evalAt[i]; + Kokkos::deep_copy(xVals, mvXVals); + + res = kokkosBSP.eval1stDeriv(xVals, 0); + + auto mvRes = Kokkos::create_mirror_view(res); + Kokkos::deep_copy(mvRes, res); + + double xDiff = std::fabs(derivX) - std::fabs(mvRes(0)); + double yDiff = std::fabs(derivY) - std::fabs(mvRes(1)); + if (xDiff > EPSILON || yDiff > EPSILON) { + std::cout << "Test " << i+1 << " failed, eval at: " << evalAt[i] << std::endl; + std::cout << "Difference: x = " << xDiff << " y = " << yDiff << std::endl; + std::cout << "SERIAL 1st deriv: x = " << derivX << " y = " << derivY << std::endl; + std::cout << "KOKKOS 1st deriv: x = " << mvRes(0) << " y = " << mvRes(1) << std::endl; + retVal = 1; + } + } } Kokkos::finalize(); return retVal; From 6c5b232cf7f07f4c1a843db858d4771832f6a1cd Mon Sep 17 00:00:00 2001 From: hsiehhRPI <112642746+hsiehhRPI@users.noreply.github.com> Date: Mon, 4 May 2026 13:54:48 -0400 Subject: [PATCH 71/73] Update testKokkos2D1stDeriv.cpp Fixed the indentation --- testKokkos2D1stDeriv.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testKokkos2D1stDeriv.cpp b/testKokkos2D1stDeriv.cpp index 30b66bd..e6ea614 100644 --- a/testKokkos2D1stDeriv.cpp +++ b/testKokkos2D1stDeriv.cpp @@ -18,9 +18,9 @@ int main(int argc, char* argv[]) { int retVal; if (argc != 3) { std::cerr<< "Input arguments: " << std::endl; - std::cerr << "input csv need these columns: "; - std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; - return 1; + std::cerr << "input csv need these columns: "; + std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; + return 1; } Kokkos::initialize(argc, argv); From ea33d98d7d47ce715357a37f055f4e2c32fa3185 Mon Sep 17 00:00:00 2001 From: hsiehhRPI <112642746+hsiehhRPI@users.noreply.github.com> Date: Mon, 4 May 2026 13:55:48 -0400 Subject: [PATCH 72/73] Update testKokkos2D2ndDeriv.cpp Fixed the indentation and formatting --- testKokkos2D2ndDeriv.cpp | 106 +++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/testKokkos2D2ndDeriv.cpp b/testKokkos2D2ndDeriv.cpp index d40847f..c329f14 100644 --- a/testKokkos2D2ndDeriv.cpp +++ b/testKokkos2D2ndDeriv.cpp @@ -26,63 +26,63 @@ int main(int argc, char* argv[]) { Kokkos::initialize(argc, argv); { #ifdef KOKKOS_ENABLE_CUDA - #define MemSpace Kokkos::CudaSpace + #define MemSpace Kokkos::CudaSpace #endif - #ifndef MemSpace - #define MemSpace Kokkos::HostSpace - #endif + #ifndef MemSpace + #define MemSpace Kokkos::HostSpace + #endif - using ExecutionSpace = MemSpace::execution_space; + using ExecutionSpace = MemSpace::execution_space; + + std::string inputCSV = argv[1]; + int extensionPos = inputCSV.rfind("."); + int slashPos = inputCSV.rfind("/"); + std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); + double expectedCurveLength = std::stod(argv[2]); + auto curve = CurveReader::readCurveInfo(inputCSV); - std::string inputCSV = argv[1]; - int extensionPos = inputCSV.rfind("."); - int slashPos = inputCSV.rfind("/"); - std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); - double expectedCurveLength = std::stod(argv[2]); - auto curve = CurveReader::readCurveInfo(inputCSV); - - SplineInterp::BSpline2d serialBSP; - if (curve.x.size() == 2) { - serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); - } - else { - serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); - } - - std::vector ctrlPtsX, ctrlPtsY, knots, weight; - int order; - serialBSP.x.getpara(order, ctrlPtsX, knots, weight); - serialBSP.y.getpara(order, ctrlPtsY, knots, weight); - - BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); - - std::vector evalAt = {0, 0.2, 0.41, 0.5, 0.66, 0.73, 0.75, 0.89, 0.94, 1}; - for (int i = 0; i < 10; i++) { - double derivX = serialBSP.x.evalSecondDeriv(evalAt[i]); - double derivY = serialBSP.y.evalSecondDeriv(evalAt[i]); + SplineInterp::BSpline2d serialBSP; + if (curve.x.size() == 2) { + serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); + } + else { + serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); + } - Kokkos::View res("Result", 2); - - Kokkos::View xVals("paraCoor", 1); - auto mvXVals = Kokkos::create_mirror_view(xVals); - mvXVals(0) = evalAt[i]; - Kokkos::deep_copy(xVals, mvXVals); - - res = kokkosBSP.eval2ndDeriv(xVals, 0); - auto mvRes = Kokkos::create_mirror_view(res); - Kokkos::deep_copy(mvRes, res); - - double xDiff = std::fabs(derivX - mvRes(0)); - double yDiff = std::fabs(derivY - mvRes(1)); - - if (xDiff > EPSILON || yDiff > EPSILON) { - std::cout << "Test " << i+1 << " failed, eval at: " << evalAt[i] << std::endl; - std::cout << "Difference: x = " << xDiff << " y = " << derivY << std::endl; - std::cout << "SERIAL 2nd deriv: x = " << derivX << ", " << derivY << std::endl; - std::cout << "KOKKOS 2nd deriv: x = " << mvRes(0) << ", " << mvRes(1) << std::endl; - retVal = 1; - } - } + std::vector ctrlPtsX, ctrlPtsY, knots, weight; + int order; + serialBSP.x.getpara(order, ctrlPtsX, knots, weight); + serialBSP.y.getpara(order, ctrlPtsY, knots, weight); + + BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); + + std::vector evalAt = {0, 0.2, 0.41, 0.5, 0.66, 0.73, 0.75, 0.89, 0.94, 1}; + for (int i = 0; i < 10; i++) { + double derivX = serialBSP.x.evalSecondDeriv(evalAt[i]); + double derivY = serialBSP.y.evalSecondDeriv(evalAt[i]); + + Kokkos::View res("Result", 2); + + Kokkos::View xVals("paraCoor", 1); + auto mvXVals = Kokkos::create_mirror_view(xVals); + mvXVals(0) = evalAt[i]; + Kokkos::deep_copy(xVals, mvXVals); + + res = kokkosBSP.eval2ndDeriv(xVals, 0); + auto mvRes = Kokkos::create_mirror_view(res); + Kokkos::deep_copy(mvRes, res); + + double xDiff = std::fabs(derivX - mvRes(0)); + double yDiff = std::fabs(derivY - mvRes(1)); + + if (xDiff > EPSILON || yDiff > EPSILON) { + std::cout << "Test " << i+1 << " failed, eval at: " << evalAt[i] << std::endl; + std::cout << "Difference: x = " << xDiff << " y = " << derivY << std::endl; + std::cout << "SERIAL 2nd deriv: x = " << derivX << ", " << derivY << std::endl; + std::cout << "KOKKOS 2nd deriv: x = " << mvRes(0) << ", " << mvRes(1) << std::endl; + retVal = 1; + } + } } Kokkos::finalize(); return retVal; From 0c9f9c668f36738f64d1f17cb6f667b8e772e860 Mon Sep 17 00:00:00 2001 From: Hsieh Date: Thu, 7 May 2026 18:29:07 -0400 Subject: [PATCH 73/73] Ran bash script and additional formatting fix --- BSplineKokkos.h | 845 +++++++++++++++++------------------- BSplineKokkos2D.h | 679 +++++++++++++++-------------- CMakeLists.txt | 28 +- testKokkos1stDerivative.cpp | 196 ++++----- testKokkos2D1stDeriv.cpp | 122 +++--- testKokkos2D2ndDeriv.cpp | 122 +++--- testSplineKokkos2DBase.cpp | 250 ++++++----- testSplineKokkosBase.cpp | 352 ++++++++------- 8 files changed, 1256 insertions(+), 1338 deletions(-) diff --git a/BSplineKokkos.h b/BSplineKokkos.h index cddd676..173c1a6 100644 --- a/BSplineKokkos.h +++ b/BSplineKokkos.h @@ -12,480 +12,421 @@ template class BSplineKokkos { public: - using MemSpace = typename ExecutionSpace::memory_space; - - //Constructor for just 1 spline(Would this be used often?) - BSplineKokkos(int order_p, std::vector& ctrlPts_x, std::vector& ctrlPts_y, std::vector& knotsI) { - //In the original implementation, we had the x and y components separated and was storing redundant knots information - //The implementation now change to interleave the x and y coordinates - //We store just 1 set of knots rather than 2 - //std::cout << "Start BSpline Construction" << std::endl; - Kokkos::View orderV("Orders", 1); - auto host_orderV = Kokkos::create_mirror_view(orderV); - host_orderV(0) = order_p; - order = orderV; - Kokkos::deep_copy(order, host_orderV); - //std::cout << "Order inputted" << std::endl; - //Initialize control points and their offset - Kokkos::View ctrlPtsV("CtrlPoints", 2*ctrlPts_x.size()); - //Create the mirror on host so we can access the vector values - auto host_ctrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); - //std::cout << "ctrlPts size: " << host_ctrlPtsV.extent(0) << std::endl; - - for (int i = 0; i < ctrlPts_x.size(); i++) { - host_ctrlPtsV(2*i) = ctrlPts_x[i]; - host_ctrlPtsV((2*i)+1) = ctrlPts_y[i]; - } - - ctrlPts = ctrlPtsV; - Kokkos::deep_copy(ctrlPts, host_ctrlPtsV); - - Kokkos::View cPOffsetV("CtrlPointsOffset", 1); - auto host_cPOffsetV = Kokkos::create_mirror_view(cPOffsetV); - host_cPOffsetV(0) = 2*ctrlPts_x.size(); //End of ctrlPts - - cPOffset = cPOffsetV; - Kokkos::deep_copy(cPOffset, host_cPOffsetV); - - //Initialize knots and their offset - Kokkos::View knotsV("Knots", knotsI.size()); - - Kokkos::View knotsOffsetV("KnotsOffset", 1); - auto host_knotsV = Kokkos::create_mirror_view(knotsV); - auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); - host_knotsOffsetV(0) = knotsI.size(); //End of knots - - for (int i = 0; i < knotsI.size(); i++) { - host_knotsV(i) = knotsI[i]; - } - - knots = knotsV; - Kokkos::deep_copy(knots, host_knotsV); - - knotsOffset = knotsOffsetV; - Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); - - //std::cout << "All good, before derivative coe" << std::endl; - //Derivative coefficients - calculateDerivCoeff(); - //std::cout << "single spline initialization ok" << std::endl; + using MemSpace = typename ExecutionSpace::memory_space; + + //Constructor for just 1 spline(Would this be used often?) + BSplineKokkos(int order_p, std::vector& ctrlPts_x, std::vector& ctrlPts_y, std::vector& knotsI) { + //In the original implementation, we had the x and y components separated and was storing redundant knots information + //The implementation now change to interleave the x and y coordinates + //We store just 1 set of knots rather than 2 + Kokkos::View orderV("Orders", 1); + auto host_orderV = Kokkos::create_mirror_view(orderV); + host_orderV(0) = order_p; + order = orderV; + Kokkos::deep_copy(order, host_orderV); + //Initialize control points and their offset + Kokkos::View ctrlPtsV("CtrlPoints", 2*ctrlPts_x.size()); + //Create the mirror on host so we can access the vector values + auto host_ctrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); + + for (int i = 0; i < ctrlPts_x.size(); i++) { + host_ctrlPtsV(2*i) = ctrlPts_x[i]; + host_ctrlPtsV((2*i)+1) = ctrlPts_y[i]; } + ctrlPts = ctrlPtsV; + Kokkos::deep_copy(ctrlPts, host_ctrlPtsV); + Kokkos::View cPOffsetV("CtrlPointsOffset", 1); + auto host_cPOffsetV = Kokkos::create_mirror_view(cPOffsetV); + host_cPOffsetV(0) = 2*ctrlPts_x.size(); //End of ctrlPts + cPOffset = cPOffsetV; + Kokkos::deep_copy(cPOffset, host_cPOffsetV); -//Create BSpline for a vector of BSplineKokkos objects - BSplineKokkos(std::vector& splines) { - //Preallocate space for Kokkos::View - //They are fixed in size and resize is expensive - int orderSize = 0; - int ctrlPSize = 0; - int knotsSize = 0; - int cPOffSize = 0; - int kOffSize = 0; - - //Input the offsets - //Track space needed to allocate for ctrlPts & knots - for (int i = 0; i < splines.size(); i++) { - cPOffSize += splines[i].getCPOffsetSize(); - kOffSize += splines[i].getKnotsOffsetSize(); - ctrlPSize += splines[i].getCtrlPtsSize(); - knotsSize += splines[i].getKnotsSize(); - orderSize += splines[i].getOrder().extent(0); - } - //Pre-Allocate space for views - Kokkos::View orderV ("Order", orderSize); - Kokkos::View ctrlPtsV ("CtrlPts", ctrlPSize); - Kokkos::View cPOffsetV ("CtrlPtsOffset", cPOffSize); - Kokkos::View knotsV("Knots", knotsSize); - Kokkos::View knotsOffsetV ("KnotsOffset", kOffSize); - auto host_orderV = Kokkos::create_mirror_view(orderV); - auto host_ctrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); - auto host_cPOffsetV = Kokkos::create_mirror_view(cPOffsetV); - auto host_knotsV = Kokkos::create_mirror_view(knotsV); - auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); - - - std::cout << "ctrlPtsOffset size: " << cPOffsetV.extent(0)<< std::endl; - std::cout << "knotsOffset size: " << knotsOffsetV.extent(0) << std::endl; - int oidx = 0; - int cPidx = 0; - int cOidx = 0; - int kidx = 0; - int kOidx = 0; - - //Populate the views with data - int cpLast = 0; - int kLast = 0; - - //NOTE TO SELF: INDEXING MAY BE WRONG - for (int i = 0; i < splines.size(); i++) { - Kokkos::View intView = splines[i].getOrder(); - auto host_intView = Kokkos::create_mirror_view(intView); - Kokkos::deep_copy(host_intView, intView); - //Populate order - for (int j = 0; j < intView.extent(0); j++) { - host_orderV(oidx+j)= host_intView(j); - std::cout << "Spline Order: " << host_orderV(oidx+j) << std::endl; - } - oidx += host_intView.extent(0); - //Populate ctrlpts offset - //Offset the offset by the last offset in the view - intView = splines[i].getCPOffset(); - host_intView = Kokkos::create_mirror_view(intView); - Kokkos::deep_copy(host_intView, intView); - for (int j = 0; j < host_intView.extent(0); j++) { - std::cout << "\tctrlPtsOffset: " << host_intView(j) << std::endl; - std::cout << "\tcpLast: " << cpLast << std::endl; - std::cout << "cOidx: " << cOidx << std::endl; - host_cPOffsetV(cOidx+j) = host_intView(j)+cpLast; - - } - cOidx += host_intView.extent(0); - cpLast += host_intView(host_intView.extent(0)-1); - //Populate knots offset - //Offset the offset by the last offset in the view - - intView = splines[i].getKnotsOffset(); - host_intView = Kokkos::create_mirror_view(intView); - Kokkos::deep_copy(host_intView, intView); - for (int j = 0; j < host_intView.extent(0); j++) { - host_knotsOffsetV(kOidx+j) = host_intView(j)+kLast; - } - kOidx += host_intView.extent(0); - kLast += host_intView(host_intView.extent(0)-1); - //kLast = host_knotsOffsetV(kOidx-1)+(host_knotsOffsetV(kOidx-1) - host_knotsOffsetV(kOidx-2)); - - //Populate ctrlpts - Kokkos::View doubleView = splines[i].getCtrlPts(); - auto host_doubleView = Kokkos::create_mirror_view(doubleView); - Kokkos::deep_copy(host_doubleView, doubleView); - for (int j = 0; j < host_doubleView.extent(0); j++) { - host_ctrlPtsV(cPidx+j) = host_doubleView(j); - } - cPidx += host_doubleView.extent(0); - //Populate knots - doubleView = splines[i].getKnots(); - host_doubleView = Kokkos::create_mirror_view(doubleView); - Kokkos::deep_copy(host_doubleView, doubleView); - for (int j = 0; j < host_doubleView.extent(0); j++) { - host_knotsV(kidx+j) = host_doubleView(j); - } - kidx += host_doubleView.extent(0); - } - - //Update the member variables - order = orderV; - knots = knotsV; - ctrlPts = ctrlPtsV; - cPOffset = cPOffsetV; - knotsOffset = knotsOffsetV; - //Copy the modification made from the host data to the device view - Kokkos::deep_copy(order, host_orderV); - Kokkos::deep_copy(knots, host_knotsV); - Kokkos::deep_copy(ctrlPts, host_ctrlPtsV); - Kokkos::deep_copy(cPOffset, host_cPOffsetV); - Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); - - //TO DO: Work on calculate derivative coeff - calculateDerivCoeff(); + //Initialize knots and their offset + Kokkos::View knotsV("Knots", knotsI.size()); + Kokkos::View knotsOffsetV("KnotsOffset", 1); + auto host_knotsV = Kokkos::create_mirror_view(knotsV); + auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); + host_knotsOffsetV(0) = knotsI.size(); //End of knots + for (int i = 0; i < knotsI.size(); i++) { + host_knotsV(i) = knotsI[i]; } - //We perform De Boor recursion here - KOKKOS_FUNCTION void evalDeBoor (double x, int splineo, int lKnot, Kokkos::View result, const Kokkos::View order, const Kokkos::View knots, const Kokkos::View ctrlPts_1stD) const { - - int order_t = lKnot; - - int leftPtX = 0; - int leftPtY = 1; - - while (x > knots(lKnot+1)) { - lKnot++; - leftPtX+=2; - leftPtY+=2; - } - - double ptsX[3]; - double ptsY[3]; - - int idx = 0; - for (int i = leftPtX; i < leftPtX+2*(order_t); i+=2) { - ptsX[idx] = ctrlPts_1stD(i); - ptsY[idx] = ctrlPts_1stD(i+1); - idx++; - } - - auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order_t+2, lKnot+order_t)); - - //I am still working on the offset for the knots - for (int r = 1; r <= order_t; r++) { - for (int i = order_t-1; i >= r; i--) { - double alpha; - if (localKnots(i-1) == localKnots(i+order_t-r-1)) { - alpha = 0.; - } - else { - alpha = (x - localKnots(i-1))/(knots(i+order_t-r-1) - knots(i-1)); - } - ptsX[i] = (1. - alpha) * ptsX[i-1] + alpha * ptsX[i]; - ptsY[i] = (1. - alpha) * ptsY[i-1] + alpha * ptsY[i]; - } - } - - result(0) = ptsX[order_t-1]; - result(1) = ptsY[order_t-1]; + knots = knotsV; + Kokkos::deep_copy(knots, host_knotsV); - } + knotsOffset = knotsOffsetV; + Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); + + //Derivative coefficients + calculateDerivCoeff(); + } - std::vector eval1stDeriv(std::vector xVals, int splineo) const { - - int lKnot; - Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); - lKnot--; - Kokkos::View res("result", 2); - Kokkos::parallel_for("parallel call for evalDeBoors", xVals.size(), KOKKOS_CLASS_LAMBDA(int i) { - evalDeBoor(xVals[i], splineo, lKnot, res, order, knots, ctrlPts_1stD); - }); - auto mvRes = Kokkos::create_mirror_view(res); - Kokkos::deep_copy(mvRes, res); - return {mvRes(0), mvRes(1)}; +//Create BSpline for a vector of BSplineKokkos objects + BSplineKokkos(std::vector& splines) { + //Preallocate space for Kokkos::View + //They are fixed in size and resize is expensive + int orderSize = 0; + int ctrlPSize = 0; + int knotsSize = 0; + int cPOffSize = 0; + int kOffSize = 0; + + //Input the offsets + //Track space needed to allocate for ctrlPts & knots + for (int i = 0; i < splines.size(); i++) { + cPOffSize += splines[i].getCPOffsetSize(); + kOffSize += splines[i].getKnotsOffsetSize(); + ctrlPSize += splines[i].getCtrlPtsSize(); + knotsSize += splines[i].getKnotsSize(); + orderSize += splines[i].getOrder().extent(0); } - - double eval2ndDeriv(double x, int splineo) const { - auto mv_order = Kokkos::create_mirror_view(order); - Kokkos::deep_copy(mv_order, order); - if (mv_order(splineo) == 2) { - return 0; - } - //Get the left knot, leftPtX, leftPtY - int lKnot = mv_order(splineo)-1; - int leftPtX = 0; - int leftPtY = 1; - - //Make sure that we did not go over to the next spline - auto mv_knotsOffset = Kokkos::create_mirror_view(knotsOffset); - Kokkos::deep_copy(mv_knotsOffset, knotsOffset); - - int bound = mv_knotsOffset(splineo); - - auto mv_knots = Kokkos::create_mirror_view(knots); - Kokkos::deep_copy(mv_knots, knots); - while (mv_knots(lKnot+1) < x) { - lKnot+=2; - leftPtX+=2; - leftPtY+=2; - if (lKnot == bound-1) { - break; - } - } - - //Populate pts and local knot views - int order_t = mv_order(splineo)-2; - auto mv_ctrlPts_2ndD = Kokkos::create_mirror_view(ctrlPts_2ndD); - int idx = 0; - Kokkos::deep_copy(mv_ctrlPts_2ndD, ctrlPts_2ndD); - - std::cout << "Second derivative coeff" << std::endl; - for (int i = 0; i < mv_ctrlPts_2ndD.extent(0); i++) { - std::cout << mv_ctrlPts_2ndD(i) << std::endl; - } - std::cout << "------------------------" << std::endl; - Kokkos::View ptsX("ptsX", order_t); - Kokkos::View ptsY("ptsY", order_t); - auto mv_ptsX = Kokkos::create_mirror_view(ptsX); - auto mv_ptsY = Kokkos::create_mirror_view(ptsY); - - for (int i = leftPtX; i < leftPtX+order_t; i+=2) { - mv_ptsX(idx) = mv_ctrlPts_2ndD(i); - mv_ptsY(idx) = mv_ctrlPts_2ndD(i+1); - } - - //Start populating the local knots - idx = 0; - Kokkos::View localKnots("localKnots", 2*order_t-2); - auto mv_localKnots = Kokkos::create_mirror_view(localKnots); - for (int i = lKnot-order_t+2; i < lKnot+order_t; i++) { - mv_localKnots(idx) = mv_knots(i); - idx++; - } - - //Copy the data back to device - Kokkos::deep_copy(localKnots, mv_localKnots); - Kokkos::deep_copy(ptsX, mv_ptsX); - Kokkos::deep_copy(ptsY, mv_ptsY); - - Kokkos::parallel_for ("2nd derivative loop", order_t, KOKKOS_LAMBDA(int r){ - for (int i = order_t-1; i >= r+1; i--) { - double aLeft = localKnots(i-1); - double aRight = localKnots(i+order_t-(r+1)-1); - double alpha; - if (aLeft == aRight) { - alpha = 0; - } - else { - alpha = (x-aLeft)/(aRight-aLeft); - } - - ptsX(i) = (1. - alpha) * ptsX(i-1)+alpha*ptsX(i); - - } - }); - - Kokkos::deep_copy(mv_ptsX, ptsX); - return mv_ptsX(order_t-1); - + //Pre-Allocate space for views + Kokkos::View orderV ("Order", orderSize); + Kokkos::View ctrlPtsV ("CtrlPts", ctrlPSize); + Kokkos::View cPOffsetV ("CtrlPtsOffset", cPOffSize); + Kokkos::View knotsV("Knots", knotsSize); + Kokkos::View knotsOffsetV ("KnotsOffset", kOffSize); + auto host_orderV = Kokkos::create_mirror_view(orderV); + auto host_ctrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); + auto host_cPOffsetV = Kokkos::create_mirror_view(cPOffsetV); + auto host_knotsV = Kokkos::create_mirror_view(knotsV); + auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); + + int oidx = 0; + int cPidx = 0; + int cOidx = 0; + int kidx = 0; + int kOidx = 0; + + //Populate the views with data + int cpLast = 0; + int kLast = 0; + + //NOTE TO SELF: INDEXING MAY BE WRONG + for (int i = 0; i < splines.size(); i++) { + Kokkos::View intView = splines[i].getOrder(); + auto host_intView = Kokkos::create_mirror_view(intView); + Kokkos::deep_copy(host_intView, intView); + //Populate order + for (int j = 0; j < intView.extent(0); j++) { + host_orderV(oidx+j)= host_intView(j); + } + oidx += host_intView.extent(0); + //Populate ctrlpts offset + //Offset the offset by the last offset in the view + intView = splines[i].getCPOffset(); + host_intView = Kokkos::create_mirror_view(intView); + Kokkos::deep_copy(host_intView, intView); + for (int j = 0; j < host_intView.extent(0); j++) { + host_cPOffsetV(cOidx+j) = host_intView(j)+cpLast; + } + cOidx += host_intView.extent(0); + cpLast += host_intView(host_intView.extent(0)-1); + //Populate knots offset + //Offset the offset by the last offset in the view + + intView = splines[i].getKnotsOffset(); + host_intView = Kokkos::create_mirror_view(intView); + Kokkos::deep_copy(host_intView, intView); + for (int j = 0; j < host_intView.extent(0); j++) { + host_knotsOffsetV(kOidx+j) = host_intView(j)+kLast; + } + kOidx += host_intView.extent(0); + kLast += host_intView(host_intView.extent(0)-1); + + //Populate ctrlpts + Kokkos::View doubleView = splines[i].getCtrlPts(); + auto host_doubleView = Kokkos::create_mirror_view(doubleView); + Kokkos::deep_copy(host_doubleView, doubleView); + for (int j = 0; j < host_doubleView.extent(0); j++) { + host_ctrlPtsV(cPidx+j) = host_doubleView(j); + } + cPidx += host_doubleView.extent(0); + //Populate knots + doubleView = splines[i].getKnots(); + host_doubleView = Kokkos::create_mirror_view(doubleView); + Kokkos::deep_copy(host_doubleView, doubleView); + for (int j = 0; j < host_doubleView.extent(0); j++) { + host_knotsV(kidx+j) = host_doubleView(j); + } + kidx += host_doubleView.extent(0); } + //Update the member variables + order = orderV; + knots = knotsV; + ctrlPts = ctrlPtsV; + cPOffset = cPOffsetV; + knotsOffset = knotsOffsetV; + //Copy the modification made from the host data to the device view + Kokkos::deep_copy(order, host_orderV); + Kokkos::deep_copy(knots, host_knotsV); + Kokkos::deep_copy(ctrlPts, host_ctrlPtsV); + Kokkos::deep_copy(cPOffset, host_cPOffsetV); + Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); + + //TO DO: Work on calculate derivative coeff + calculateDerivCoeff(); + + } + + //We perform De Boor recursion here + KOKKOS_FUNCTION void evalDeBoor (double x, int splineo, int lKnot, Kokkos::View result, const Kokkos::View order, const Kokkos::View knots, const Kokkos::View ctrlPts_1stD) const { + + int order_t = lKnot; + int leftPtX = 0; + int leftPtY = 1; + + while (x > knots(lKnot+1)) { + lKnot++; + leftPtX+=2; + leftPtY+=2; + } + double ptsX[3]; + double ptsY[3]; + int idx = 0; + for (int i = leftPtX; i < leftPtX+2*(order_t); i+=2) { + ptsX[idx] = ctrlPts_1stD(i); + ptsY[idx] = ctrlPts_1stD(i+1); + idx++; + } + auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order_t+2, lKnot+order_t)); + + //I am still working on the offset for the knots + for (int r = 1; r <= order_t; r++) { + for (int i = order_t-1; i >= r; i--) { + double alpha; + if (localKnots(i-1) == localKnots(i+order_t-r-1)) { + alpha = 0.; + } + else { + alpha = (x - localKnots(i-1))/(knots(i+order_t-r-1) - knots(i-1)); + } + ptsX[i] = (1. - alpha) * ptsX[i-1] + alpha * ptsX[i]; + ptsY[i] = (1. - alpha) * ptsY[i-1] + alpha * ptsY[i]; + } + } - //Accessors - Kokkos::View getOrder() const {return order;} - Kokkos::View getCtrlPts() const {return ctrlPts;} - Kokkos::View getKnots() const {return knots;} - Kokkos::View getCPOffset() const {return cPOffset;} - Kokkos::View getKnotsOffset() const {return knotsOffset;} - Kokkos::View get1stD() const {return ctrlPts_1stD;} - Kokkos::View get2ndD() const {return ctrlPts_2ndD;} - + result(0) = ptsX[order_t-1]; + result(1) = ptsY[order_t-1]; + } + + std::vector eval1stDeriv(std::vector xVals, int splineo) const { + int lKnot; + Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); + lKnot--; + Kokkos::View res("result", 2); + Kokkos::parallel_for("parallel call for evalDeBoors", xVals.size(), KOKKOS_CLASS_LAMBDA(int i) { + evalDeBoor(xVals[i], splineo, lKnot, res, order, knots, ctrlPts_1stD); + }); + auto mvRes = Kokkos::create_mirror_view(res); + Kokkos::deep_copy(mvRes, res); + return {mvRes(0), mvRes(1)}; + } + + double eval2ndDeriv(double x, int splineo) const { + auto mv_order = Kokkos::create_mirror_view(order); + Kokkos::deep_copy(mv_order, order); + if (mv_order(splineo) == 2) { + return 0; + } + //Get the left knot, leftPtX, leftPtY + int lKnot = mv_order(splineo)-1; + int leftPtX = 0; + int leftPtY = 1; + + //Make sure that we did not go over to the next spline + auto mv_knotsOffset = Kokkos::create_mirror_view(knotsOffset); + Kokkos::deep_copy(mv_knotsOffset, knotsOffset); + + int bound = mv_knotsOffset(splineo); + + auto mv_knots = Kokkos::create_mirror_view(knots); + Kokkos::deep_copy(mv_knots, knots); + while (mv_knots(lKnot+1) < x) { + lKnot+=2; + leftPtX+=2; + leftPtY+=2; + if (lKnot == bound-1) { + break; + } + } - int getCPOffsetSize() const {return cPOffset.extent(0);} - int getKnotsOffsetSize() const {return knotsOffset.extent(0);} - int getCtrlPtsSize() const {return ctrlPts.extent(0);} - int getKnotsSize() const {return knots.extent(0);} - int getOrderSize() const {return order.extent(0);} + //Populate pts and local knot views + int order_t = mv_order(splineo)-2; + auto mv_ctrlPts_2ndD = Kokkos::create_mirror_view(ctrlPts_2ndD); + int idx = 0; + Kokkos::deep_copy(mv_ctrlPts_2ndD, ctrlPts_2ndD); - double getCtrlPtCoor(int BspIdx, int cPIdx, char coor) const { - if (coor == 'x') { - //Find the correct offset - return ctrlPts(cPOffset(2*BspIdx)+cPIdx); - } - else { - return ctrlPts(cPOffset(2*BspIdx+1)+cPIdx); - } + for (int i = 0; i < mv_ctrlPts_2ndD.extent(0); i++) { + std::cout << mv_ctrlPts_2ndD(i) << std::endl; } - double getKnotCoor(int BspIdx, int kIdx, char coor) const { - if (coor == 'x') { - return knots(knotsOffset(2*BspIdx)+kIdx); - } - else { - return knots(knotsOffset(2*BspIdx+1)+kIdx); - } + + Kokkos::View ptsX("ptsX", order_t); + Kokkos::View ptsY("ptsY", order_t); + auto mv_ptsX = Kokkos::create_mirror_view(ptsX); + auto mv_ptsY = Kokkos::create_mirror_view(ptsY); + + for (int i = leftPtX; i < leftPtX+order_t; i+=2) { + mv_ptsX(idx) = mv_ctrlPts_2ndD(i); + mv_ptsY(idx) = mv_ctrlPts_2ndD(i+1); + } + + //Start populating the local knots + idx = 0; + Kokkos::View localKnots("localKnots", 2*order_t-2); + auto mv_localKnots = Kokkos::create_mirror_view(localKnots); + for (int i = lKnot-order_t+2; i < lKnot+order_t; i++) { + mv_localKnots(idx) = mv_knots(i); + idx++; } - void calculateDerivCoeff() { - //Moved here from the .cpp file since it uses - //Calculate first order derivative - //Allocate the space - - //std::cout << "calculating derivative coeff" << std::endl; - Kokkos::View ctrlPts_1stDV("ctrlPts1Derivative", ctrlPts.extent(0)-(2*cPOffset.extent(0))); - Kokkos::View cP1stDOffsetV("ctrlPts1DerivativeOffset", cPOffset.extent(0)); - Kokkos::View cP2ndDOffsetV("ctrlPts2DerivativeOffset", cPOffset.extent(0)); - - auto host_cP2ndDOffsetV = Kokkos::create_mirror_view(cP2ndDOffsetV); - - auto host_cP1stDOffsetV = Kokkos::create_mirror_view(cP1stDOffsetV); - - //std::cout << "offset views and 1stctrlPts views construct" << std::endl; - - //Adjust the offset to include be 1 & 2 less than the ctrlPtsOffset - - auto host_cPOffset = Kokkos::create_mirror_view(cPOffset); - Kokkos::deep_copy(host_cPOffset, cPOffset); - if (host_cPOffset.extent(0) > 1) { - Kokkos::deep_copy(host_cPOffset, cPOffset); - for (int i = 1; i < cPOffset.extent(0); i++) { - host_cP1stDOffsetV(i) = host_cPOffset(i)-2; - host_cP2ndDOffsetV(i) = host_cPOffset(i)-4; - //std::cout << "1st: " << host_cP1stDOffsetV(i); - //std::cout << ", 2nd: " << host_cP2ndDOffsetV(i) << std::endl; - } - } - else { - host_cP1stDOffsetV(0) = host_cPOffset(0)-2; - host_cP2ndDOffsetV(0) = host_cPOffset(0)-4; - } - - //std::cout << "offset view populated" << std::endl; - - //We need to partition the x and y while we calculate the coefficient - int idx = 0; - int oidx = 0; - double deltaHold = 0; - int kidx = 2; - - auto host_knots = Kokkos::create_mirror_view(knots); - auto host_order = Kokkos::create_mirror_view(order); - auto host_ctrlPts = Kokkos::create_mirror_view(ctrlPts); - auto host_ctrlPts_1stDV = Kokkos::create_mirror_view(ctrlPts_1stDV); - - //Copy these value over - Kokkos::deep_copy(host_knots, knots); - Kokkos::deep_copy(host_order, order); - Kokkos::deep_copy(host_ctrlPts, ctrlPts); - - //std::cout << "Copied ctrlPts, knots, order" << std::endl; - //We need to keep track of the indicies of the splines - //We ignore the first ctrl point, starting at idx = 2 - for (int i = 2; i < host_ctrlPts.extent(0); i++) { - //Even indices stores all the x coordinates - //Odd indices stores all the y coordinates - if (i == host_cPOffset(idx)) { oidx++; - idx++; - } - if (i%2==0) { - double delta = double (host_order(oidx)-1)/(host_knots(kidx+host_order(oidx)-2)-host_knots(kidx-1)); - deltaHold = delta; - kidx++; - } - //std::cout << "deltaHold: " << deltaHold << std::endl; - //std::cout << "ctrlPts: "<< host_ctrlPts(i) << ", " << host_ctrlPts(i-2) << std::endl; - host_ctrlPts_1stDV(i-2) = (host_ctrlPts(i)-host_ctrlPts(i-2))*deltaHold; - } - - //std::cout << "1stD coeff populated" << std::endl; - - Kokkos::View ctrlPts_2ndDV("ctrlPts2Derivative", ctrlPts.extent(0)-(2*cPOffset.extent(0))-2); - auto host_ctrlPts_2ndDV = Kokkos::create_mirror_view(ctrlPts_2ndDV); - idx = 0; - oidx = 0; - for (int i = 2; i < host_ctrlPts_1stDV.extent(0); i++) { - if (i == host_cPOffset(idx)) { - oidx++; - idx++; - } - double delta = double(host_order(oidx)-2)/(host_knots(i+host_order(oidx)-1) - host_knots(i)); - host_ctrlPts_2ndDV(i-2) = (host_ctrlPts(i) - host_ctrlPts(i-2))*delta; - } - - Kokkos::deep_copy(cP1stDOffsetV, host_cP1stDOffsetV); - Kokkos::deep_copy(cP2ndDOffsetV, host_cP2ndDOffsetV); - Kokkos::deep_copy(ctrlPts_1stDV, host_ctrlPts_1stDV); - Kokkos::deep_copy(ctrlPts_2ndDV, host_ctrlPts_2ndDV); - - ctrlPts_2ndD = ctrlPts_2ndDV; - ctrlPts_1stD = ctrlPts_1stDV; - cP1stDOffset = cP1stDOffsetV; - cP2ndDOffset = cP2ndDOffsetV; + //Copy the data back to device + Kokkos::deep_copy(localKnots, mv_localKnots); + Kokkos::deep_copy(ptsX, mv_ptsX); + Kokkos::deep_copy(ptsY, mv_ptsY); + + Kokkos::parallel_for ("2nd derivative loop", order_t, KOKKOS_LAMBDA(int r){ + for (int i = order_t-1; i >= r+1; i--) { + double aLeft = localKnots(i-1); + double aRight = localKnots(i+order_t-(r+1)-1); + double alpha; + if (aLeft == aRight) { + alpha = 0; + } + else { + alpha = (x-aLeft)/(aRight-aLeft); + } + + ptsX(i) = (1. - alpha) * ptsX(i-1)+alpha*ptsX(i); + } + }); + + Kokkos::deep_copy(mv_ptsX, ptsX); + return mv_ptsX(order_t-1); + + } + +//Accessors + Kokkos::View getOrder() const {return order;} + Kokkos::View getCtrlPts() const {return ctrlPts;} + Kokkos::View getKnots() const {return knots;} + Kokkos::View getCPOffset() const {return cPOffset;} + Kokkos::View getKnotsOffset() const {return knotsOffset;} + Kokkos::View get1stD() const {return ctrlPts_1stD;} + Kokkos::View get2ndD() const {return ctrlPts_2ndD;} + + int getCPOffsetSize() const {return cPOffset.extent(0);} + int getKnotsOffsetSize() const {return knotsOffset.extent(0);} + int getCtrlPtsSize() const {return ctrlPts.extent(0);} + int getKnotsSize() const {return knots.extent(0);} + int getOrderSize() const {return order.extent(0);} + + double getCtrlPtCoor(int BspIdx, int cPIdx, char coor) const { + if (coor == 'x') { + //Find the correct offset + return ctrlPts(cPOffset(2*BspIdx)+cPIdx); + } + else { + return ctrlPts(cPOffset(2*BspIdx+1)+cPIdx); } - - private: - - Kokkos::View order; - - //CtrlPts, knots, weights and their offsets - Kokkos::View ctrlPts; - Kokkos::View cPOffset; - Kokkos::View knots; - Kokkos::View knotsOffset; - - //The 1st and 2nd derivatives - Kokkos::View ctrlPts_1stD; - Kokkos::View cP1stDOffset; - Kokkos::View ctrlPts_2ndD; - Kokkos::View cP2ndDOffset; + } + double getKnotCoor(int BspIdx, int kIdx, char coor) const { + if (coor == 'x') { + return knots(knotsOffset(2*BspIdx)+kIdx); + } + else { + return knots(knotsOffset(2*BspIdx+1)+kIdx); + } + } + + void calculateDerivCoeff() { + //Moved here from the .cpp file since it uses + //Calculate first order derivative + //Allocate the space + + Kokkos::View ctrlPts_1stDV("ctrlPts1Derivative", ctrlPts.extent(0)-(2*cPOffset.extent(0))); + Kokkos::View cP1stDOffsetV("ctrlPts1DerivativeOffset", cPOffset.extent(0)); + Kokkos::View cP2ndDOffsetV("ctrlPts2DerivativeOffset", cPOffset.extent(0)); + + auto host_cP2ndDOffsetV = Kokkos::create_mirror_view(cP2ndDOffsetV); + auto host_cP1stDOffsetV = Kokkos::create_mirror_view(cP1stDOffsetV); + + //Adjust the offset to include be 1 & 2 less than the ctrlPtsOffset + auto host_cPOffset = Kokkos::create_mirror_view(cPOffset); + Kokkos::deep_copy(host_cPOffset, cPOffset); + if (host_cPOffset.extent(0) > 1) { + Kokkos::deep_copy(host_cPOffset, cPOffset); + for (int i = 1; i < cPOffset.extent(0); i++) { + host_cP1stDOffsetV(i) = host_cPOffset(i)-2; + host_cP2ndDOffsetV(i) = host_cPOffset(i)-4; + } + } + else { + host_cP1stDOffsetV(0) = host_cPOffset(0)-2; + host_cP2ndDOffsetV(0) = host_cPOffset(0)-4; + } + //We need to partition the x and y while we calculate the coefficient + int idx = 0; + int oidx = 0; + double deltaHold = 0; + int kidx = 2; + + auto host_knots = Kokkos::create_mirror_view(knots); + auto host_order = Kokkos::create_mirror_view(order); + auto host_ctrlPts = Kokkos::create_mirror_view(ctrlPts); + auto host_ctrlPts_1stDV = Kokkos::create_mirror_view(ctrlPts_1stDV); + + //Copy these value over + Kokkos::deep_copy(host_knots, knots); + Kokkos::deep_copy(host_order, order); + Kokkos::deep_copy(host_ctrlPts, ctrlPts); + + //We need to keep track of the indicies of the splines + //We ignore the first ctrl point, starting at idx = 2 + for (int i = 2; i < host_ctrlPts.extent(0); i++) { + //Even indices stores all the x coordinates + //Odd indices stores all the y coordinates + if (i == host_cPOffset(idx)) { + oidx++; + idx++; + } + if (i%2==0) { + double delta = double (host_order(oidx)-1)/(host_knots(kidx+host_order(oidx)-2)-host_knots(kidx-1)); + deltaHold = delta; + kidx++; + } + host_ctrlPts_1stDV(i-2) = (host_ctrlPts(i)-host_ctrlPts(i-2))*deltaHold; + } + + Kokkos::deep_copy(cP1stDOffsetV, host_cP1stDOffsetV); + Kokkos::deep_copy(ctrlPts_1stDV, host_ctrlPts_1stDV); + + ctrlPts_1stD = ctrlPts_1stDV; + cP1stDOffset = cP1stDOffsetV; + } + +private: + + Kokkos::View order; + + //CtrlPts, knots, weights and their offsets + Kokkos::View ctrlPts; + Kokkos::View cPOffset; + Kokkos::View knots; + Kokkos::View knotsOffset; + + //The 1st and 2nd derivatives + Kokkos::View ctrlPts_1stD; + Kokkos::View cP1stDOffset; + Kokkos::View ctrlPts_2ndD; + Kokkos::View cP2ndDOffset; }; #endif diff --git a/BSplineKokkos2D.h b/BSplineKokkos2D.h index 1ed24ec..03af85a 100644 --- a/BSplineKokkos2D.h +++ b/BSplineKokkos2D.h @@ -11,373 +11,370 @@ template class BSplineKokkos2D { public: - using MemSpace = typename ExecutionSpace::memory_space; + using MemSpace = typename ExecutionSpace::memory_space; - BSplineKokkos2D(int order_p, std::vector& ctrlPts_x, std::vector& ctrlPts_y, std::vector& knotsI) { - Kokkos::View orderV("Orders", 1); - auto host_orderV = Kokkos::create_mirror_view(orderV); - host_orderV(0) = order_p; - order = orderV; - Kokkos::deep_copy(order, host_orderV); - - Kokkos::View ctrlPtsV("ctrlPts", ctrlPts_x.size()); - auto host_ctrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); - for (int i = 0; i < ctrlPts_x.size(); i++) { - host_ctrlPtsV(i, 0) = ctrlPts_x[i]; - host_ctrlPtsV(i, 1) = ctrlPts_y[i]; - } - ctrlPts = ctrlPtsV; - Kokkos::deep_copy(ctrlPts, host_ctrlPtsV); - - Kokkos::View cpOffsetV("cpOffset", 1); - auto host_cpOffsetV = Kokkos::create_mirror_view(cpOffsetV); - host_cpOffsetV(0) = ctrlPts_x.size(); - host_cpOffsetV(0) = ctrlPts_x.size(); - - cpOffset = cpOffsetV; - Kokkos::deep_copy(cpOffset, host_cpOffsetV); - - Kokkos::View knotsV("knots", knotsI.size()); - auto host_knotsV = Kokkos::create_mirror_view(knotsV); - for (int i = 0; i < knotsI.size(); i++) { - host_knotsV(i) = knotsI[i]; - } - knots = knotsV; - Kokkos::deep_copy(knots, host_knotsV); - - Kokkos::View knotsOffsetV("knotsOffset", 1); - auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); - host_knotsOffsetV(0) = knotsI.size(); - knotsOffset = knotsOffsetV; - Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); + BSplineKokkos2D(int order_p, std::vector& ctrlPts_x, std::vector& ctrlPts_y, std::vector& knotsI) { + Kokkos::View orderV("Orders", 1); + auto host_orderV = Kokkos::create_mirror_view(orderV); + host_orderV(0) = order_p; + order = orderV; + Kokkos::deep_copy(order, host_orderV); + + Kokkos::View ctrlPtsV("ctrlPts", ctrlPts_x.size()); + auto host_ctrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); + for (int i = 0; i < ctrlPts_x.size(); i++) { + host_ctrlPtsV(i, 0) = ctrlPts_x[i]; + host_ctrlPtsV(i, 1) = ctrlPts_y[i]; + } + ctrlPts = ctrlPtsV; + Kokkos::deep_copy(ctrlPts, host_ctrlPtsV); - //TO DO: Implement 1st&2nd Coef function - calculateDerivCoeff(); + Kokkos::View cpOffsetV("cpOffset", 1); + auto host_cpOffsetV = Kokkos::create_mirror_view(cpOffsetV); + host_cpOffsetV(0) = ctrlPts_x.size(); + host_cpOffsetV(0) = ctrlPts_x.size(); + cpOffset = cpOffsetV; + Kokkos::deep_copy(cpOffset, host_cpOffsetV); + + Kokkos::View knotsV("knots", knotsI.size()); + auto host_knotsV = Kokkos::create_mirror_view(knotsV); + for (int i = 0; i < knotsI.size(); i++) { + host_knotsV(i) = knotsI[i]; + } + knots = knotsV; + Kokkos::deep_copy(knots, host_knotsV); + + Kokkos::View knotsOffsetV("knotsOffset", 1); + auto host_knotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); + host_knotsOffsetV(0) = knotsI.size(); + knotsOffset = knotsOffsetV; + Kokkos::deep_copy(knotsOffset, host_knotsOffsetV); + + //TO DO: Implement 1st&2nd Coef function + calculateDerivCoeff(); + + } + + BSplineKokkos2D(std::vector& multiSplines) { + //Loop over all the splines to know how much space to allocate + int orderSize = 0; + int ctrlPtsSize = 0; + int cpOffsetSize = 0; + int knotSize = 0; + int knotsOffsetSize = 0; + + for (int i = 0; i < multiSplines.size(); i++) { + orderSize += multiSplines[i].getOrder().extent(0); + ctrlPtsSize += multiSplines[i].getCtrlPts().extent(0); + cpOffsetSize += multiSplines[i].getCPOffset().extent(0); + knotSize += multiSplines[i].getKnots().extent(0); + knotsOffsetSize += multiSplines[i].getKnotsOffset().extent(0); } - BSplineKokkos2D(std::vector& multiSplines) { - //Loop over all the splines to know how much space to allocate - int orderSize = 0; - int ctrlPtsSize = 0; - int cpOffsetSize = 0; - int knotSize = 0; - int knotsOffsetSize = 0; - - for (int i = 0; i < multiSplines.size(); i++) { - orderSize += multiSplines[i].getOrder().extent(0); - ctrlPtsSize += multiSplines[i].getCtrlPts().extent(0); - cpOffsetSize += multiSplines[i].getCPOffset().extent(0); - knotSize += multiSplines[i].getKnots().extent(0); - knotsOffsetSize += multiSplines[i].getKnotsOffset().extent(0); - } - - //Populate the views - Kokkos::View orderV ("order", orderSize); - Kokkos::View ctrlPtsV("ctrlPts", ctrlPtsSize); - Kokkos::View cPOffsetV("ctrlPtsOffset", cpOffsetSize); - Kokkos::View knotsV("knots", knotSize); - Kokkos::View knotsOffsetV("knotsOffset", knotsOffsetSize); - - //Create the mirror view on host to move the data over - auto mvOrderV = Kokkos::create_mirror_view(orderV); - auto mvCtrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); - auto mvCPOffsetV = Kokkos::create_mirror_view(cPOffsetV); - auto mvKnotsV = Kokkos::create_mirror_view(knotsV); - auto mvKnotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); - //Copy the data over - int oidx = 0; - int cPidx = 0; - int cOidx = 0; - int kidx = 0; - int kOidx = 0; - for (int i = 0; i < multiSplines.size(); i++) { - //Populate orders - Kokkos::View intView = multiSplines[i].getOrder(); - auto mvIntView = Kokkos::create_mirror_view(intView); - Kokkos::deep_copy(mvIntView, intView); - for (int j = 0; j < intView.extent(0); j++) { - mvOrderV(oidx+j) = mvIntView(j); - } - oidx += mvIntView.extent(0); - - //Populate ctrlPts - Kokkos::View double2DView = multiSplines[i].getCtrlPts(); - auto mvDouble2DView = Kokkos::create_mirror_view(double2DView); - Kokkos::deep_copy(mvDouble2DView, double2DView); - for (int j = 0; j < mvDouble2DView.extent(0); j++) { - mvCtrlPtsV(cPidx+j, 0) = mvDouble2DView(j, 0); - mvCtrlPtsV(cPidx+j, 1) = mvDouble2DView(j, 1); - } - cPidx += mvDouble2DView.extent(0); - - //Populate ctrlPtsOffset - intView = multiSplines[i].getCPOffset(); - mvIntView = Kokkos::create_mirror_view(intView); - Kokkos::deep_copy(mvIntView, intView); - - for (int j = 0; j < intView.extent(0); j++) { - mvCPOffsetV(cOidx + j) = intView(j); - } - cOidx += intView.extent(0); - - //Populate knots - Kokkos::View doubleView = multiSplines[i].getKnots(); - auto mvDoubleView = Kokkos::create_mirror_view(doubleView); - Kokkos::deep_copy(mvDoubleView, doubleView); - - for (int j = 0; j < doubleView.extent(0); j++) { - mvKnotsV(kidx+j) = doubleView(j); - } - kidx += doubleView.extent(0); - - //Populate knots offset - intView = multiSplines[i].getKnotsOffset(); - mvIntView = Kokkos::create_mirror_view(intView); - Kokkos::deep_copy(mvIntView, intView); - - for (int j = 0; j < intView.extent(0); j++) { - mvKnotsOffsetV(kOidx+j) = mvIntView(j); - } - kOidx += mvIntView.extent(0); - } - - //Copy the data on host to device - order = orderV; - ctrlPts = ctrlPtsV; - cpOffset = cPOffsetV; - knots = knotsV; - knotsOffset = knotsOffsetV; - - Kokkos::deep_copy(order, mvOrderV); - Kokkos::deep_copy(ctrlPts, mvCtrlPtsV); - Kokkos::deep_copy(cpOffset, mvCPOffsetV); - Kokkos::deep_copy(knots, mvKnotsV); - Kokkos::deep_copy(knotsOffset, mvKnotsOffsetV); - - //TO DO: Implement 1st&2nd Coef function - calculateDerivCoeff(); + //Populate the views + Kokkos::View orderV ("order", orderSize); + Kokkos::View ctrlPtsV("ctrlPts", ctrlPtsSize); + Kokkos::View cPOffsetV("ctrlPtsOffset", cpOffsetSize); + Kokkos::View knotsV("knots", knotSize); + Kokkos::View knotsOffsetV("knotsOffset", knotsOffsetSize); + + //Create the mirror view on host to move the data over + auto mvOrderV = Kokkos::create_mirror_view(orderV); + auto mvCtrlPtsV = Kokkos::create_mirror_view(ctrlPtsV); + auto mvCPOffsetV = Kokkos::create_mirror_view(cPOffsetV); + auto mvKnotsV = Kokkos::create_mirror_view(knotsV); + auto mvKnotsOffsetV = Kokkos::create_mirror_view(knotsOffsetV); + //Copy the data over + int oidx = 0; + int cPidx = 0; + int cOidx = 0; + int kidx = 0; + int kOidx = 0; + for (int i = 0; i < multiSplines.size(); i++) { + //Populate orders + Kokkos::View intView = multiSplines[i].getOrder(); + auto mvIntView = Kokkos::create_mirror_view(intView); + Kokkos::deep_copy(mvIntView, intView); + for (int j = 0; j < intView.extent(0); j++) { + mvOrderV(oidx+j) = mvIntView(j); + } + oidx += mvIntView.extent(0); + + //Populate ctrlPts + Kokkos::View double2DView = multiSplines[i].getCtrlPts(); + auto mvDouble2DView = Kokkos::create_mirror_view(double2DView); + Kokkos::deep_copy(mvDouble2DView, double2DView); + for (int j = 0; j < mvDouble2DView.extent(0); j++) { + mvCtrlPtsV(cPidx+j, 0) = mvDouble2DView(j, 0); + mvCtrlPtsV(cPidx+j, 1) = mvDouble2DView(j, 1); + } + cPidx += mvDouble2DView.extent(0); + + //Populate ctrlPtsOffset + intView = multiSplines[i].getCPOffset(); + mvIntView = Kokkos::create_mirror_view(intView); + Kokkos::deep_copy(mvIntView, intView); + + for (int j = 0; j < intView.extent(0); j++) { + mvCPOffsetV(cOidx + j) = intView(j); + } + cOidx += intView.extent(0); + + //Populate knots + Kokkos::View doubleView = multiSplines[i].getKnots(); + auto mvDoubleView = Kokkos::create_mirror_view(doubleView); + Kokkos::deep_copy(mvDoubleView, doubleView); + + for (int j = 0; j < doubleView.extent(0); j++) { + mvKnotsV(kidx+j) = doubleView(j); + } + kidx += doubleView.extent(0); + + //Populate knots offset + intView = multiSplines[i].getKnotsOffset(); + mvIntView = Kokkos::create_mirror_view(intView); + Kokkos::deep_copy(mvIntView, intView); + + for (int j = 0; j < intView.extent(0); j++) { + mvKnotsOffsetV(kOidx+j) = mvIntView(j); + } + kOidx += mvIntView.extent(0); + } + //Copy the data on host to device + order = orderV; + ctrlPts = ctrlPtsV; + cpOffset = cPOffsetV; + knots = knotsV; + knotsOffset = knotsOffsetV; + + Kokkos::deep_copy(order, mvOrderV); + Kokkos::deep_copy(ctrlPts, mvCtrlPtsV); + Kokkos::deep_copy(cpOffset, mvCPOffsetV); + Kokkos::deep_copy(knots, mvKnotsV); + Kokkos::deep_copy(knotsOffset, mvKnotsOffsetV); + + //TO DO: Implement 1st&2nd Coef function + calculateDerivCoeff(); + + } + + void calculateDerivCoeff() { + //Allocate the views we need + Kokkos::View ctrlPts1stDV("ctrlPts1stDeriv", ctrlPts.extent(0)-cpOffset.extent(0)); + Kokkos::View cP1stDOffsetV("cP1stDOffset", cpOffset.extent(0)); + Kokkos::View cP2ndDOffsetV("cP2ndDOffset", cpOffset.extent(0)); + + //Set up the offset views + auto mvCP1stDOffsetV = Kokkos::create_mirror_view(cP1stDOffsetV); + auto mvCP2ndDOffsetV = Kokkos::create_mirror_view(cP2ndDOffsetV); + + auto mvCPOffset = Kokkos::create_mirror_view(cpOffset); + + if (mvCPOffset.extent(0) > 1) { + Kokkos::deep_copy(mvCPOffset, cpOffset); + for (int i = 1; i < mvCPOffset.extent(0); i++) { + mvCP1stDOffsetV(i) = mvCPOffset(i)-1; + mvCP2ndDOffsetV(i) = mvCPOffset(i)-2; + } + } + else { + mvCP1stDOffsetV(0) = mvCPOffset(0)-1; + mvCP2ndDOffsetV(0) = mvCPOffset(0)-2; } - void calculateDerivCoeff() { - //Allocate the views we need - Kokkos::View ctrlPts1stDV("ctrlPts1stDeriv", ctrlPts.extent(0)-cpOffset.extent(0)); - Kokkos::View cP1stDOffsetV("cP1stDOffset", cpOffset.extent(0)); - Kokkos::View cP2ndDOffsetV("cP2ndDOffset", cpOffset.extent(0)); - - //Set up the offset views - auto mvCP1stDOffsetV = Kokkos::create_mirror_view(cP1stDOffsetV); - auto mvCP2ndDOffsetV = Kokkos::create_mirror_view(cP2ndDOffsetV); - - auto mvCPOffset = Kokkos::create_mirror_view(cpOffset); - - if (mvCPOffset.extent(0) > 1) { - Kokkos::deep_copy(mvCPOffset, cpOffset); - for (int i = 1; i < mvCPOffset.extent(0); i++) { - mvCP1stDOffsetV(i) = mvCPOffset(i)-1; - mvCP2ndDOffsetV(i) = mvCPOffset(i)-2; - } - } - else { - mvCP1stDOffsetV(0) = mvCPOffset(0)-1; - mvCP2ndDOffsetV(0) = mvCPOffset(0)-2; - } - - auto mvOrder = Kokkos::create_mirror_view(order); - auto mvKnots = Kokkos::create_mirror_view(knots); - auto mvCtrlPts = Kokkos::create_mirror_view(ctrlPts); - auto mvCtrlPts1stDV = Kokkos::create_mirror_view(ctrlPts1stDV); - Kokkos::deep_copy(mvOrder, order); - Kokkos::deep_copy(mvKnots, knots); - Kokkos::deep_copy(mvCtrlPts, ctrlPts); + auto mvOrder = Kokkos::create_mirror_view(order); + auto mvKnots = Kokkos::create_mirror_view(knots); + auto mvCtrlPts = Kokkos::create_mirror_view(ctrlPts); + auto mvCtrlPts1stDV = Kokkos::create_mirror_view(ctrlPts1stDV); + Kokkos::deep_copy(mvOrder, order); + Kokkos::deep_copy(mvKnots, knots); + Kokkos::deep_copy(mvCtrlPts, ctrlPts); //Calculate 1st derivative coef - int offidx = 0; //Offset index - int oidx = 0; //Order index - for (int i = 1; i < mvCtrlPts1stDV.extent(0)+1; i++) { - if (i == mvCP1stDOffsetV(offidx)+1) { - oidx++; - offidx++; - continue; - } - //We need to check whether we are on the border for the next spline in our structure - double delta = double(mvOrder(oidx)-1) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i)); - - mvCtrlPts1stDV(i-1, 0) = (mvCtrlPts(i, 0) - mvCtrlPts(i-1, 0))*delta; - mvCtrlPts1stDV(i-1, 1) = (mvCtrlPts(i, 1) - mvCtrlPts(i-1, 1))*delta; - } - - //Calculate 2nd derivative coef - Kokkos::View ctrlPts2ndDV("ctrlPts2ndDeriv", ctrlPts.extent(0)-(2*cpOffset.extent(0))); - auto mvCtrlPts2ndDV = Kokkos::create_mirror_view(ctrlPts2ndDV); - - offidx = 0; - oidx = 0; - for (int i = 1; i < ctrlPts1stDV.extent(0); i++) { - if (i == mvCP2ndDOffsetV(offidx)+2) { - oidx++; - offidx++; - continue; - } - double delta = double(mvOrder(oidx)-2) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i+1)); - - mvCtrlPts2ndDV(i-1, 0) = (mvCtrlPts1stDV(i, 0) - mvCtrlPts1stDV(i-1, 0)) * delta; - mvCtrlPts2ndDV(i-1, 1) = (mvCtrlPts1stDV(i, 1) - mvCtrlPts1stDV(i-1, 1)) * delta; - } - - //Copy to device - Kokkos::deep_copy(cP1stDOffsetV, mvCP1stDOffsetV); - Kokkos::deep_copy(cP2ndDOffsetV, mvCP2ndDOffsetV); - Kokkos::deep_copy(ctrlPts1stDV, mvCtrlPts1stDV); - Kokkos::deep_copy(ctrlPts2ndDV, mvCtrlPts2ndDV); - - cp1stDOffset = cP1stDOffsetV; - cp2ndDOffset = cP2ndDOffsetV; - ctrlPts1stD = ctrlPts1stDV; - ctrlPts2ndD = ctrlPts2ndDV; - + int offidx = 0; //Offset index + int oidx = 0; //Order index + for (int i = 1; i < mvCtrlPts1stDV.extent(0)+1; i++) { + if (i == mvCP1stDOffsetV(offidx)+1) { + oidx++; + offidx++; + continue; + } + //We need to check whether we are on the border for the next spline in our structure + double delta = double(mvOrder(oidx)-1) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i)); + + mvCtrlPts1stDV(i-1, 0) = (mvCtrlPts(i, 0) - mvCtrlPts(i-1, 0))*delta; + mvCtrlPts1stDV(i-1, 1) = (mvCtrlPts(i, 1) - mvCtrlPts(i-1, 1))*delta; + } + //Calculate 2nd derivative coef + Kokkos::View ctrlPts2ndDV("ctrlPts2ndDeriv", ctrlPts.extent(0)-(2*cpOffset.extent(0))); + auto mvCtrlPts2ndDV = Kokkos::create_mirror_view(ctrlPts2ndDV); + + offidx = 0; + oidx = 0; + for (int i = 1; i < ctrlPts1stDV.extent(0); i++) { + if (i == mvCP2ndDOffsetV(offidx)+2) { + oidx++; + offidx++; + continue; + } + double delta = double(mvOrder(oidx)-2) / (mvKnots(i+mvOrder(oidx)-1) - mvKnots(i+1)); + + mvCtrlPts2ndDV(i-1, 0) = (mvCtrlPts1stDV(i, 0) - mvCtrlPts1stDV(i-1, 0)) * delta; + mvCtrlPts2ndDV(i-1, 1) = (mvCtrlPts1stDV(i, 1) - mvCtrlPts1stDV(i-1, 1)) * delta; } - KOKKOS_FUNCTION void evalDeBoor(double x, int splineo, int lKnot, Kokkos::View result, const Kokkos::View order, const Kokkos::View knots, const Kokkos::View ctrlPts_1stD) const { - //DeBoor's algorithm for BSpline 1st deriv calculation - int order_t = lKnot; - int leftPt = 0; - - while (x > knots(lKnot+1)) { - lKnot++; - leftPt++; - } - - //Allocate temporary points - double ptsX[3]; - double ptsY[3]; - - int idx = 0; - for (int i = leftPt; i < leftPt + order_t; i++) { - ptsX[idx] = ctrlPts_1stD(i, 0); - ptsY[idx] = ctrlPts_1stD(i, 1); - idx++; - } - - auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order_t+2, lKnot+order_t)); - - //Calculation loop - for (int r = 1; r <= order_t; r++) { - for(int i = order_t-1; i >= r; i--) { - double alpha; - if (localKnots(i-1) - localKnots(i+order_t-r-1) > 1e-12) { - alpha = 0; - } - else { - alpha = (x - localKnots(i-1)) / (knots(i+order_t-r-1) - knots(i-1)); - } - ptsX[i] = (1. - alpha) * ptsX[i-1]+alpha * ptsX[i]; - ptsY[i] = (1. - alpha) * ptsY[i-1]+alpha * ptsY[i]; - } - - result(0) = ptsX[order_t-1]; - result(1) = ptsY[order_t-1]; - } + //Copy to device + Kokkos::deep_copy(cP1stDOffsetV, mvCP1stDOffsetV); + Kokkos::deep_copy(cP2ndDOffsetV, mvCP2ndDOffsetV); + Kokkos::deep_copy(ctrlPts1stDV, mvCtrlPts1stDV); + Kokkos::deep_copy(ctrlPts2ndDV, mvCtrlPts2ndDV); + + cp1stDOffset = cP1stDOffsetV; + cp2ndDOffset = cP2ndDOffsetV; + ctrlPts1stD = ctrlPts1stDV; + ctrlPts2ndD = ctrlPts2ndDV; + + + } + + KOKKOS_FUNCTION void evalDeBoor(double x, int splineo, int lKnot, Kokkos::View result, const Kokkos::View order, const Kokkos::View knots, const Kokkos::View ctrlPts_1stD) const { + //DeBoor's algorithm for BSpline 1st deriv calculation + int order_t = lKnot; + int leftPt = 0; + + while (x > knots(lKnot+1)) { + lKnot++; + leftPt++; } - - Kokkos::View eval1stDeriv(Kokkos::View xVals, int splineo) const { - int lKnot; - Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); - lKnot--; - Kokkos::View res("result", 2); - Kokkos::parallel_for("parallel evalDeBoors", xVals.size(), KOKKOS_CLASS_LAMBDA(int i){ - evalDeBoor(xVals(i), splineo, lKnot, res, order, knots, ctrlPts1stD); - v}); - return res; + + //Allocate temporary points + double ptsX[3]; + double ptsY[3]; + + int idx = 0; + for (int i = leftPt; i < leftPt + order_t; i++) { + ptsX[idx] = ctrlPts_1stD(i, 0); + ptsY[idx] = ctrlPts_1stD(i, 1); + idx++; } + auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order_t+2, lKnot+order_t)); + + //Calculation loop + for (int r = 1; r <= order_t; r++) { + for(int i = order_t-1; i >= r; i--) { + double alpha; + if (localKnots(i-1) - localKnots(i+order_t-r-1) > 1e-12) { + alpha = 0; + } + else { + alpha = (x - localKnots(i-1)) / (knots(i+order_t-r-1) - knots(i-1)); + } + ptsX[i] = (1. - alpha) * ptsX[i-1]+alpha * ptsX[i]; + ptsY[i] = (1. - alpha) * ptsY[i-1]+alpha * ptsY[i]; + } + + result(0) = ptsX[order_t-1]; + result(1) = ptsY[order_t-1]; + } + } + + Kokkos::View eval1stDeriv(Kokkos::View xVals, int splineo) const { + int lKnot; + Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); + lKnot--; + Kokkos::View res("result", 2); + Kokkos::parallel_for("parallel evalDeBoors", xVals.size(), KOKKOS_CLASS_LAMBDA(int i){ + evalDeBoor(xVals(i), splineo, lKnot, res, order, knots, ctrlPts1stD); + }); + return res; + } + + //Second derivative calculation + KOKKOS_FUNCTION void evalDeBoor2(double x, int splineo, int lKnot, Kokkos::View result, const Kokkos::View order, const Kokkos::View knots, const Kokkos::View ctrlPts_2ndD) const { + if (order(splineo) == 2) { + result(0) = 0; + result(1) = 0; + return; + } - //Second derivative calculation - KOKKOS_FUNCTION void evalDeBoor2(double x, int splineo, int lKnot, Kokkos::View result, const Kokkos::View order, const Kokkos::View knots, const Kokkos::View ctrlPts_2ndD) const { - if (order(splineo) == 2) { - result(0) = 0; - result(1) = 0; - return; - } - - int order_t = lKnot-1; - int leftPt = 0; - - while (knots(lKnot+1) < x) { - lKnot++; - leftPt++; - } - - double ptsX[3]; - double ptsY[3]; - - int idx = 0; - for (int i = leftPt; i < leftPt+order_t; i++) { - ptsX[idx] = ctrlPts_2ndD(i, 0); - ptsY[idx] = ctrlPts_2ndD(i, 1); - idx++; - } - - auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order_t+2, lKnot+order_t)); - - for (int r = 1; r <= order_t; r++) { - for (int i = order_t-1; i >= r; i--) { - double aLeft = localKnots(i-1); - double aRight = localKnots(i+order_t-r-1); - double alpha; - if (aLeft == aRight) { - alpha = 0.; - } - else { - alpha = (x - aLeft) / (aRight - aLeft); - } - - ptsX[i] = (1. - alpha) * ptsX[i-1] + alpha * ptsX[i]; - ptsY[i] = (1. - alpha) * ptsY[i-1] + alpha * ptsY[i]; - } - } - - result(0) = ptsX[order_t-1]; - result(1) = ptsY[order_t-1]; + int order_t = lKnot-1; + int leftPt = 0; + while (knots(lKnot+1) < x) { + lKnot++; + leftPt++; } - Kokkos::View eval2ndDeriv(Kokkos::View xVals, int splineo) const { - int lKnot; - Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); - lKnot--; - Kokkos::View res("result", 2); - Kokkos::parallel_for("parallel evalDeBoors 2", xVals.size(), KOKKOS_CLASS_LAMBDA(int i) { - evalDeBoor2(xVals(i), splineo, lKnot, res, order, knots, ctrlPts2ndD); - }); - return res; + double ptsX[3]; + double ptsY[3]; + + int idx = 0; + for (int i = leftPt; i < leftPt+order_t; i++) { + ptsX[idx] = ctrlPts_2ndD(i, 0); + ptsY[idx] = ctrlPts_2ndD(i, 1); + idx++; } + auto localKnots = Kokkos::subview(knots, Kokkos::pair(lKnot-order_t+2, lKnot+order_t)); + + for (int r = 1; r <= order_t; r++) { + for (int i = order_t-1; i >= r; i--) { + double aLeft = localKnots(i-1); + double aRight = localKnots(i+order_t-r-1); + double alpha; + if (aLeft == aRight) { + alpha = 0.; + } + else { + alpha = (x - aLeft) / (aRight - aLeft); + } + ptsX[i] = (1. - alpha) * ptsX[i-1] + alpha * ptsX[i]; + ptsY[i] = (1. - alpha) * ptsY[i-1] + alpha * ptsY[i]; + } + } - //Accessors - Kokkos::View getOrder() const {return order;} - Kokkos::View getCtrlPts() const {return ctrlPts;} - Kokkos::View getCPOffset() const {return cpOffset;} - Kokkos::View getKnots() const {return knots;} - Kokkos::View getKnotsOffset() const {return knotsOffset;} - Kokkos::View getCP1stD() const {return ctrlPts1stD;} - Kokkos::View getCP1stDOffset() const {return cp1stDOffset;} - Kokkos::View getCP2ndD() const {return ctrlPts2ndD;} - Kokkos::View getCP2ndDOffset() const {return cp2ndDOffset;} + result(0) = ptsX[order_t-1]; + result(1) = ptsY[order_t-1]; + + } + + Kokkos::View eval2ndDeriv(Kokkos::View xVals, int splineo) const { + int lKnot; + Kokkos::deep_copy(lKnot, Kokkos::subview(order, splineo)); + lKnot--; + Kokkos::View res("result", 2); + Kokkos::parallel_for("parallel evalDeBoors 2", xVals.size(), KOKKOS_CLASS_LAMBDA(int i) { + evalDeBoor2(xVals(i), splineo, lKnot, res, order, knots, ctrlPts2ndD); + }); + return res; + } + + //Accessors + Kokkos::View getOrder() const {return order;} + Kokkos::View getCtrlPts() const {return ctrlPts;} + Kokkos::View getCPOffset() const {return cpOffset;} + Kokkos::View getKnots() const {return knots;} + Kokkos::View getKnotsOffset() const {return knotsOffset;} + Kokkos::View getCP1stD() const {return ctrlPts1stD;} + Kokkos::View getCP1stDOffset() const {return cp1stDOffset;} + Kokkos::View getCP2ndD() const {return ctrlPts2ndD;} + Kokkos::View getCP2ndDOffset() const {return cp2ndDOffset;} private: - Kokkos::View order; - Kokkos::View ctrlPts; - Kokkos::View cpOffset; - Kokkos::View knots; - Kokkos::View knotsOffset; - Kokkos::View ctrlPts1stD; - Kokkos::View ctrlPts2ndD; - Kokkos::View cp1stDOffset; - Kokkos::View cp2ndDOffset; + Kokkos::View order; + Kokkos::View ctrlPts; + Kokkos::View cpOffset; + Kokkos::View knots; + Kokkos::View knotsOffset; + Kokkos::View ctrlPts1stD; + Kokkos::View ctrlPts2ndD; + Kokkos::View cp1stDOffset; + Kokkos::View cp2ndDOffset; }; diff --git a/CMakeLists.txt b/CMakeLists.txt index 3200706..0479639 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -186,50 +186,50 @@ set_tests_properties(testDiscoverTopo_L11pts PROPERTIES add_executable(testSplineKokkosBase testSplineKokkosBase.cpp) target_link_libraries(testSplineKokkosBase PRIVATE splineInterp curveReader modelGen2d splineKokkos Kokkos::kokkos) add_test(NAME testBSplineKokkosSerialStraightEdge - COMMAND ./testSplineKokkosBase ${testDataDir}/testCurveStrightLine.csv 9) + COMMAND ./testSplineKokkosBase ${testDataDir}/testCurveStrightLine.csv 9) add_test(NAME testBSplineKokkosSerial_edge_2pts - COMMAND ./testSplineKokkosBase ${testDataDir}/testCurve2pts.csv 1) + COMMAND ./testSplineKokkosBase ${testDataDir}/testCurve2pts.csv 1) #TEST FOR BSPLINEKOKKOS 1ST DERIVATIVE add_executable(testKokkos1stDerivative testKokkos1stDerivative.cpp) target_link_libraries(testKokkos1stDerivative PRIVATE splineInterp curveReader modelGen2d splineKokkos Kokkos::kokkos) add_test(NAME testKokkos1stDerivativeStraightEdge - COMMAND ./testKokkos1stDerivative contour_test_data/testCurveStraightLine.csv 9) + COMMAND ./testKokkos1stDerivative contour_test_data/testCurveStraightLine.csv 9) add_test(NAME testKokkos1stDerivativeEdge2Pts - COMMAND ./testKokkos1stDerivative contour_test_data/testCurve2pts.csv 1) + COMMAND ./testKokkos1stDerivative contour_test_data/testCurve2pts.csv 1) add_test(NAME testKokkos1stDerivativeSingleEdge - COMMAND ./testKokkos1stDerivative ${testDataDir}/testCurveSplineFitting.csv 12.2685) + COMMAND ./testKokkos1stDerivative ${testDataDir}/testCurveSplineFitting.csv 12.2685) #TEST FOR BSPLINEKOKKOS2D CONSTRUCTOR add_executable(testSplineKokkos2DBase testSplineKokkos2DBase.cpp) target_link_libraries(testSplineKokkos2DBase PRIVATE splineInterp curveReader modelGen2d splineKokkos2D Kokkos::kokkos) add_test(NAME testSplineKokkos2DStraightEdge - COMMAND ./testSplineKokkos2DBase contour_test_data/testCurveStraightLine.csv 9) + COMMAND ./testSplineKokkos2DBase contour_test_data/testCurveStraightLine.csv 9) add_test(NAME testSplineKokkos2D2Pts - COMMAND ./testSplineKokkos2DBase contour_test_data/testCurve2pts.csv 1) + COMMAND ./testSplineKokkos2DBase contour_test_data/testCurve2pts.csv 1) add_test(NAME testSplineKokkos2DSingleEdge - COMMAND ./testSplineKokkos2DBase ${testDataDir}/testCurveSplineFitting.csv 12.2685) + COMMAND ./testSplineKokkos2DBase ${testDataDir}/testCurveSplineFitting.csv 12.2685) #TEST FOR BSPLINEKOKKOS2D 1ST DERIVATIVE add_executable(testKokkos2D1stDeriv testKokkos2D1stDeriv.cpp) target_link_libraries(testKokkos2D1stDeriv PRIVATE splineInterp curveReader modelGen2d splineKokkos2D Kokkos::kokkos) add_test(NAME testDeriv2DStraightEdge - COMMAND ./testKokkos2D1stDeriv contour_test_data/testCurveStraightLine.csv 9) + COMMAND ./testKokkos2D1stDeriv contour_test_data/testCurveStraightLine.csv 9) add_test(NAME testDeriv2D2Pts - COMMAND ./testKokkos2D1stDeriv contour_test_data/testCurve2pts.csv 1) + COMMAND ./testKokkos2D1stDeriv contour_test_data/testCurve2pts.csv 1) add_test(NAME testDeriv2DSingleEdge - COMMAND ./testKokkos2D1stDeriv ${testDataDir}/testCurveSplineFitting.csv 12.2685) + COMMAND ./testKokkos2D1stDeriv ${testDataDir}/testCurveSplineFitting.csv 12.2685) #TEST FOR BSPLINEKOKKOS2D 2ND DERIVATIVE add_executable(testKokkos2D2ndDeriv testKokkos2D2ndDeriv.cpp) target_link_libraries(testKokkos2D2ndDeriv PRIVATE splineInterp curveReader modelGen2d splineKokkos2D Kokkos::kokkos) add_test(NAME test2NDDeriv2DStraightEdge - COMMAND ./testKokkos2D2ndDeriv contour_test_data/testCurveStraightLine.csv 9) + COMMAND ./testKokkos2D2ndDeriv contour_test_data/testCurveStraightLine.csv 9) add_test(NAME test2NDDeriv2D2Pts - COMMAND ./testKokkos2D2ndDeriv contour_test_data/testCurve2pts.csv 1) + COMMAND ./testKokkos2D2ndDeriv contour_test_data/testCurve2pts.csv 1) add_test(NAME test2NDDerive2DSingleEdge - COMMAND ./testKokkos2D2ndDeriv contour_test_data/testSplineFitting.csv 12.2685) + COMMAND ./testKokkos2D2ndDeriv contour_test_data/testSplineFitting.csv 12.2685) diff --git a/testKokkos1stDerivative.cpp b/testKokkos1stDerivative.cpp index 15fb8ba..119014d 100644 --- a/testKokkos1stDerivative.cpp +++ b/testKokkos1stDerivative.cpp @@ -16,123 +16,119 @@ template void printDView(Kokkos::View& dView) { - auto host_dView = Kokkos::create_mirror_view(dView); - Kokkos::deep_copy(host_dView, dView); - for (int i = 0; i < host_dView.extent(0); i++) { - std::cout << host_dView(i) << std::endl; - } + auto host_dView = Kokkos::create_mirror_view(dView); + Kokkos::deep_copy(host_dView, dView); + for (int i = 0; i < host_dView.extent(0); i++) { + std::cout << host_dView(i) << std::endl; + } } template void printIView(Kokkos::View& iView) { - auto host_iView = Kokkos::create_mirror_view(iView); - Kokkos::deep_copy(host_iView, iView); - for (int i = 0; i < host_iView.extent(0); i++) { - std::cout << host_iView(i) << std::endl; - } + auto host_iView = Kokkos::create_mirror_view(iView); + Kokkos::deep_copy(host_iView, iView); + for (int i = 0; i < host_iView.extent(0); i++) { + std::cout << host_iView(i) << std::endl; + } } template void printSpline(BSplineKokkos spline) { - std::cout << "Spline content" << std::endl; - Kokkos::View dView = spline.getCtrlPts(); - std::cout << "CtrlPts" << std::endl; - printDView(dView); - Kokkos::View iView = spline.getCPOffset(); - std::cout << "CtrlPts Offset" << std::endl; - printIView(iView); - dView = spline.getKnots(); - std::cout << "Knots" << std::endl; - printDView(dView); - iView = spline.getKnotsOffset(); - std::cout << "Knots Offset" << std::endl; - printIView(iView); - iView = spline.getOrder(); - std::cout << "Order" << std::endl; - printIView(iView); + std::cout << "Spline content" << std::endl; + Kokkos::View dView = spline.getCtrlPts(); + std::cout << "CtrlPts" << std::endl; + printDView(dView); + Kokkos::View iView = spline.getCPOffset(); + std::cout << "CtrlPts Offset" << std::endl; + printIView(iView); + dView = spline.getKnots(); + std::cout << "Knots" << std::endl; + printDView(dView); + iView = spline.getKnotsOffset(); + std::cout << "Knots Offset" << std::endl; + printIView(iView); + iView = spline.getOrder(); + std::cout << "Order" << std::endl; + printIView(iView); } void printVector(const std::string& name, std::vector& vector) { - std::cout << name << ": " << vector.size() << std::endl; - for (int i = 0; i < vector.size(); i++) { - std::cout << vector[i] << std::endl; - } + std::cout << name << ": " << vector.size() << std::endl; + for (int i = 0; i < vector.size(); i++) { + std::cout << vector[i] << std::endl; + } } double EPSILON = 1e-12; int main(int argc, char* argv[]) { - int retVal = 0; - - if (argc != 3) { - //Check for the arguments needed - std::cerr<< "Input arguments: " << std::endl; - std::cerr << "input csv need these columns: "; - std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; - return 1; + int retVal = 0; + if (argc != 3) { + //Check for the arguments needed + std::cerr<< "Input arguments: " << std::endl; + std::cerr << "input csv need these columns: "; + std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; + return 1; + } + Kokkos::initialize(argc, argv); + { + //Check for what memory space we should use + //Sticking to just cuda space or host space for now + #ifdef KOKKOS_ENABLE_CUDA + #define MemSpace Kokkos::CudaSpace + #endif + #ifndef MemSpace + #define MemSpace Kokkos::HostSpace + #endif + using ExecutionSpace = MemSpace::execution_space; + + std::string inputCSV = argv[1]; + int extensionPos = inputCSV.rfind("."); + int slashPos = inputCSV.rfind("/"); + std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); + double expectedCurveLength = std::stod(argv[2]); + auto curve = CurveReader::readCurveInfo(inputCSV); + + //Construct BSpline2d object + SplineInterp::BSpline2d serialBSP; + if (curve.x.size() == 2) { + serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); + } else { + serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); } - Kokkos::initialize(argc, argv); - { - - //Check for what memory space we should use - //Sticking to just cuda space or host space for now - - #ifdef KOKKOS_ENABLE_CUDA - #define MemSpace Kokkos::CudaSpace - #endif - #ifndef MemSpace - #define MemSpace Kokkos::HostSpace - #endif - - using ExecutionSpace = MemSpace::execution_space; - - std::string inputCSV = argv[1]; - int extensionPos = inputCSV.rfind("."); - int slashPos = inputCSV.rfind("/"); - std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); - double expectedCurveLength = std::stod(argv[2]); - auto curve = CurveReader::readCurveInfo(inputCSV); - - //Construct BSpline2d object - SplineInterp::BSpline2d serialBSP; - if (curve.x.size() == 2) { - serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); - } else { - serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); - } - - std::vector ctrlPtsX, ctrlPtsY, knots, weight; - int order; - - //Get the info from serial spline, we will feed this to kokkos spline - serialBSP.x.getpara(order, ctrlPtsX, knots, weight); - serialBSP.y.getpara(order, ctrlPtsY, knots, weight); - - BSplineKokkos kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); - //printSpline(kokkosBSP); - std::vector evalAt = {0, 0.2, 0.41, 0.5, 0.66, 0.73, 0.75, 0.89, 0.94, 1}; - - for (int i = 0; i < 10; i++) { - double derivX = serialBSP.x.evalFirstDeriv(evalAt[i]); - double derivY = serialBSP.y.evalFirstDeriv(evalAt[i]); - std::vector kokkos1stDeriv = kokkosBSP.eval1stDeriv({evalAt[i]}, 0); - double kokkosDerivX = kokkos1stDeriv[0]; - double kokkosDerivY = kokkos1stDeriv[1]; - - double derivXDiff = std::fabs(derivX) - std::fabs(kokkosDerivX); - double derivYDiff = std::fabs(derivY) - std::fabs(kokkosDerivY); - - if (derivXDiff > EPSILON || derivYDiff > EPSILON) { - std::cout << "Test " << i+1 << " failed, eval at: " << evalAt[i] << std::endl; - std::cout << "EPSILON = " << EPSILON << std::endl; - std::cout << "SERIAL/KOKKOS DIFFERENCE: xcoor = " << derivXDiff << " ycoor = " << derivYDiff << std::endl; - std::cout << "SERIAL 1st Derivative: x = " << derivX << " y = " << derivY << std::endl; - std::cout << "KOKKOS 1st Derivative: x = " << kokkosDerivX << " y = " << kokkosDerivY << std::endl; - retVal = 1; - } - } + std::vector ctrlPtsX, ctrlPtsY, knots, weight; + int order; + + //Get the info from serial spline, we will feed this to kokkos spline + serialBSP.x.getpara(order, ctrlPtsX, knots, weight); + serialBSP.y.getpara(order, ctrlPtsY, knots, weight); + + BSplineKokkos kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); + //printSpline(kokkosBSP); + std::vector evalAt = {0, 0.2, 0.41, 0.5, 0.66, 0.73, 0.75, 0.89, 0.94, 1}; + + for (int i = 0; i < 10; i++) { + double derivX = serialBSP.x.evalFirstDeriv(evalAt[i]); + double derivY = serialBSP.y.evalFirstDeriv(evalAt[i]); + std::vector kokkos1stDeriv = kokkosBSP.eval1stDeriv({evalAt[i]}, 0); + double kokkosDerivX = kokkos1stDeriv[0]; + double kokkosDerivY = kokkos1stDeriv[1]; + + double derivXDiff = std::fabs(derivX) - std::fabs(kokkosDerivX); + double derivYDiff = std::fabs(derivY) - std::fabs(kokkosDerivY); + + if (derivXDiff > EPSILON || derivYDiff > EPSILON) { + std::cout << "Test " << i+1 << " failed, eval at: " << evalAt[i] << std::endl; + std::cout << "EPSILON = " << EPSILON << std::endl; + std::cout << "SERIAL/KOKKOS DIFFERENCE: xcoor = " << derivXDiff << " ycoor = " << derivYDiff << std::endl; + std::cout << "SERIAL 1st Derivative: x = " << derivX << " y = " << derivY << std::endl; + std::cout << "KOKKOS 1st Derivative: x = " << kokkosDerivX << " y = " << kokkosDerivY << std::endl; + retVal = 1; + } } - Kokkos::finalize(); - return retVal; + + } + Kokkos::finalize(); + return retVal; } diff --git a/testKokkos2D1stDeriv.cpp b/testKokkos2D1stDeriv.cpp index d1f98f7..3fc17d5 100644 --- a/testKokkos2D1stDeriv.cpp +++ b/testKokkos2D1stDeriv.cpp @@ -15,76 +15,74 @@ double EPSILON = 1e-12; int main(int argc, char* argv[]) { - int retVal; - if (argc != 3) { - std::cerr<< "Input arguments: " << std::endl; - std::cerr << "input csv need these columns: "; - std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; - return 1; - } + int retVal; + if (argc != 3) { + std::cerr<< "Input arguments: " << std::endl; + std::cerr << "input csv need these columns: "; + std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; + return 1; + } - Kokkos::initialize(argc, argv); - { - #ifdef KOKKOS_ENABLE_CUDA - #define MemSpace Kokkos::CudaSpace - #endif - #ifndef MemSpace - #define MemSpace Kokkos::HostSpace - #endif + Kokkos::initialize(argc, argv); + { + #ifdef KOKKOS_ENABLE_CUDA + #define MemSpace Kokkos::CudaSpace + #endif + #ifndef MemSpace + #define MemSpace Kokkos::HostSpace + #endif - using ExecutionSpace = MemSpace::execution_space; + using ExecutionSpace = MemSpace::execution_space; - std::string inputCSV = argv[1]; - int extensionPos = inputCSV.rfind("."); - int slashPos = inputCSV.rfind("/"); - std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); - double expectedCurveLength = std::stod(argv[2]); - auto curve = CurveReader::readCurveInfo(inputCSV); + std::string inputCSV = argv[1]; + int extensionPos = inputCSV.rfind("."); + int slashPos = inputCSV.rfind("/"); + std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); + double expectedCurveLength = std::stod(argv[2]); + auto curve = CurveReader::readCurveInfo(inputCSV); - //Construct BSpline2d object - SplineInterp::BSpline2d serialBSP; - if (curve.x.size() == 2) { - serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); - } else { - serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); - } - - std::vector ctrlPtsX, ctrlPtsY, knots, weight; - int order; + //Construct BSpline2d object + SplineInterp::BSpline2d serialBSP; + if (curve.x.size() == 2) { + serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); + } else { + serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); + } - //Get the info from serial spline, we will feed this to kokkos spline - serialBSP.x.getpara(order, ctrlPtsX, knots, weight); - serialBSP.y.getpara(order, ctrlPtsY, knots, weight); + std::vector ctrlPtsX, ctrlPtsY, knots, weight; + int order; - BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); + //Get the info from serial spline, we will feed this to kokkos spline + serialBSP.x.getpara(order, ctrlPtsX, knots, weight); + serialBSP.y.getpara(order, ctrlPtsY, knots, weight); - std::vector evalAt = {0, 0.2, 0.41, 0.5, 0.66, 0.73, 0.75, 0.89, 0.94, 1}; - for (int i = 0; i < 10; i++) { - double derivX = serialBSP.x.evalFirstDeriv(evalAt[i]); - double derivY = serialBSP.y.evalFirstDeriv(evalAt[i]); - - Kokkos::View res("deriv result", 2); - Kokkos::View xVals ("paraCoor", 1); - auto mvXVals = Kokkos::create_mirror_view(xVals); - mvXVals(0) = evalAt[i]; - Kokkos::deep_copy(xVals, mvXVals); + BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); - res = kokkosBSP.eval1stDeriv(xVals, 0); - - auto mvRes = Kokkos::create_mirror_view(res); - Kokkos::deep_copy(mvRes, res); + std::vector evalAt = {0, 0.2, 0.41, 0.5, 0.66, 0.73, 0.75, 0.89, 0.94, 1}; + for (int i = 0; i < 10; i++) { + double derivX = serialBSP.x.evalFirstDeriv(evalAt[i]); + double derivY = serialBSP.y.evalFirstDeriv(evalAt[i]); + + Kokkos::View res("deriv result", 2); + Kokkos::View xVals ("paraCoor", 1); + auto mvXVals = Kokkos::create_mirror_view(xVals); + mvXVals(0) = evalAt[i]; + Kokkos::deep_copy(xVals, mvXVals); + res = kokkosBSP.eval1stDeriv(xVals, 0); + auto mvRes = Kokkos::create_mirror_view(res); + Kokkos::deep_copy(mvRes, res); - double xDiff = std::fabs(derivX) - std::fabs(mvRes(0)); - double yDiff = std::fabs(derivY) - std::fabs(mvRes(1)); - if (xDiff > EPSILON || yDiff > EPSILON) { - std::cout << "Test " << i+1 << " failed, eval at: " << evalAt[i] << std::endl; - std::cout << "Difference: x = " << xDiff << " y = " << yDiff << std::endl; - std::cout << "SERIAL 1st deriv: x = " << derivX << " y = " << derivY << std::endl; - std::cout << "KOKKOS 1st deriv: x = " << mvRes(0) << " y = " << mvRes(1) << std::endl; - retVal = 1; - } - } + double xDiff = std::fabs(derivX) - std::fabs(mvRes(0)); + double yDiff = std::fabs(derivY) - std::fabs(mvRes(1)); + if (xDiff > EPSILON || yDiff > EPSILON) { + std::cout << "Test " << i+1 << " failed, eval at: " << evalAt[i] << std::endl; + std::cout << "Difference: x = " << xDiff << " y = " << yDiff << std::endl; + std::cout << "SERIAL 1st deriv: x = " << derivX << " y = " << derivY << std::endl; + std::cout << "KOKKOS 1st deriv: x = " << mvRes(0) << " y = " << mvRes(1) << std::endl; + retVal = 1; + } } - Kokkos::finalize(); - return retVal; + } + Kokkos::finalize(); + return retVal; } diff --git a/testKokkos2D2ndDeriv.cpp b/testKokkos2D2ndDeriv.cpp index d40847f..b58a315 100644 --- a/testKokkos2D2ndDeriv.cpp +++ b/testKokkos2D2ndDeriv.cpp @@ -15,76 +15,74 @@ double EPSILON = 1e-12; int main(int argc, char* argv[]) { - int retVal = 0; - if (argc != 3) { - std::cerr<< "Input arguments: " << std::endl; - std::cerr << "input csv need these columns: "; - std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; - return 1; - } + int retVal = 0; + if (argc != 3) { + std::cerr<< "Input arguments: " << std::endl; + std::cerr << "input csv need these columns: "; + std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; + return 1; + } + + Kokkos::initialize(argc, argv); + { + #ifdef KOKKOS_ENABLE_CUDA + #define MemSpace Kokkos::CudaSpace + #endif + #ifndef MemSpace + #define MemSpace Kokkos::HostSpace + #endif + + using ExecutionSpace = MemSpace::execution_space; - Kokkos::initialize(argc, argv); - { - #ifdef KOKKOS_ENABLE_CUDA - #define MemSpace Kokkos::CudaSpace - #endif - #ifndef MemSpace - #define MemSpace Kokkos::HostSpace - #endif - - using ExecutionSpace = MemSpace::execution_space; - - std::string inputCSV = argv[1]; - int extensionPos = inputCSV.rfind("."); - int slashPos = inputCSV.rfind("/"); - std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); - double expectedCurveLength = std::stod(argv[2]); - auto curve = CurveReader::readCurveInfo(inputCSV); + std::string inputCSV = argv[1]; + int extensionPos = inputCSV.rfind("."); + int slashPos = inputCSV.rfind("/"); + std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); + double expectedCurveLength = std::stod(argv[2]); + auto curve = CurveReader::readCurveInfo(inputCSV); - SplineInterp::BSpline2d serialBSP; - if (curve.x.size() == 2) { - serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); - } - else { - serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); - } + SplineInterp::BSpline2d serialBSP; + if (curve.x.size() == 2) { + serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); + } + else { + serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); + } - std::vector ctrlPtsX, ctrlPtsY, knots, weight; - int order; - serialBSP.x.getpara(order, ctrlPtsX, knots, weight); - serialBSP.y.getpara(order, ctrlPtsY, knots, weight); + std::vector ctrlPtsX, ctrlPtsY, knots, weight; + int order; + serialBSP.x.getpara(order, ctrlPtsX, knots, weight); + serialBSP.y.getpara(order, ctrlPtsY, knots, weight); - BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); + BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); - std::vector evalAt = {0, 0.2, 0.41, 0.5, 0.66, 0.73, 0.75, 0.89, 0.94, 1}; - for (int i = 0; i < 10; i++) { - double derivX = serialBSP.x.evalSecondDeriv(evalAt[i]); - double derivY = serialBSP.y.evalSecondDeriv(evalAt[i]); - - Kokkos::View res("Result", 2); + std::vector evalAt = {0, 0.2, 0.41, 0.5, 0.66, 0.73, 0.75, 0.89, 0.94, 1}; + for (int i = 0; i < 10; i++) { + double derivX = serialBSP.x.evalSecondDeriv(evalAt[i]); + double derivY = serialBSP.y.evalSecondDeriv(evalAt[i]); - Kokkos::View xVals("paraCoor", 1); - auto mvXVals = Kokkos::create_mirror_view(xVals); - mvXVals(0) = evalAt[i]; - Kokkos::deep_copy(xVals, mvXVals); + Kokkos::View res("Result", 2); + Kokkos::View xVals("paraCoor", 1); + auto mvXVals = Kokkos::create_mirror_view(xVals); + mvXVals(0) = evalAt[i]; + Kokkos::deep_copy(xVals, mvXVals); - res = kokkosBSP.eval2ndDeriv(xVals, 0); - auto mvRes = Kokkos::create_mirror_view(res); - Kokkos::deep_copy(mvRes, res); + res = kokkosBSP.eval2ndDeriv(xVals, 0); + auto mvRes = Kokkos::create_mirror_view(res); + Kokkos::deep_copy(mvRes, res); - double xDiff = std::fabs(derivX - mvRes(0)); - double yDiff = std::fabs(derivY - mvRes(1)); + double xDiff = std::fabs(derivX - mvRes(0)); + double yDiff = std::fabs(derivY - mvRes(1)); - if (xDiff > EPSILON || yDiff > EPSILON) { - std::cout << "Test " << i+1 << " failed, eval at: " << evalAt[i] << std::endl; - std::cout << "Difference: x = " << xDiff << " y = " << derivY << std::endl; - std::cout << "SERIAL 2nd deriv: x = " << derivX << ", " << derivY << std::endl; - std::cout << "KOKKOS 2nd deriv: x = " << mvRes(0) << ", " << mvRes(1) << std::endl; - retVal = 1; - } - } + if (xDiff > EPSILON || yDiff > EPSILON) { + std::cout << "Test " << i+1 << " failed, eval at: " << evalAt[i] << std::endl; + std::cout << "Difference: x = " << xDiff << " y = " << derivY << std::endl; + std::cout << "SERIAL 2nd deriv: x = " << derivX << ", " << derivY << std::endl; + std::cout << "KOKKOS 2nd deriv: x = " << mvRes(0) << ", " << mvRes(1) << std::endl; + retVal = 1; + } } - Kokkos::finalize(); - return retVal; - + } + Kokkos::finalize(); + return retVal; } diff --git a/testSplineKokkos2DBase.cpp b/testSplineKokkos2DBase.cpp index ccf97d5..11f5b97 100644 --- a/testSplineKokkos2DBase.cpp +++ b/testSplineKokkos2DBase.cpp @@ -20,136 +20,130 @@ double EPSILON = 1e-12; int main(int argc, char* argv[]) { - //We check how many arguments are given - int retVal = 0; - if (argc != 3) { - std::cerr<< "Input arguments: " << std::endl; - std::cerr << "input csv need these columns: "; - std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; - return 1; + //We check how many arguments are given + int retVal = 0; + if (argc != 3) { + std::cerr<< "Input arguments: " << std::endl; + std::cerr << "input csv need these columns: "; + std::cerr << "coordinate x, coordinate y, coordinate z,isOnCurve,angle,isMdlVtx" << std::endl; + return 1; + } + Kokkos::initialize(argc, argv); + { + #ifdef KOKKOS_ENABLE_CUDA + #define MemSpace Kokkos::CudaSpace + #endif + #ifndef MemSpace + #define MemSpace Kokkos::HostSpace + #endif + + using ExecutionSpace = MemSpace::execution_space; + + std::string inputCSV = argv[1]; + int extensionPos = inputCSV.rfind("."); + int slashPos = inputCSV.rfind("/"); + std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); + double expectedCurveLength = std::stod(argv[2]); + auto curve = CurveReader::readCurveInfo(inputCSV); + + //Construct BSpline2d object + SplineInterp::BSpline2d serialBSP; + if (curve.x.size() == 2) { + serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); + } else { + serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); } - Kokkos::initialize(argc, argv); - { - - #ifdef KOKKOS_ENABLE_CUDA - #define MemSpace Kokkos::CudaSpace - #endif - #ifndef MemSpace - #define MemSpace Kokkos::HostSpace - #endif - - using ExecutionSpace = MemSpace::execution_space; - - std::string inputCSV = argv[1]; - int extensionPos = inputCSV.rfind("."); - int slashPos = inputCSV.rfind("/"); - std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); - double expectedCurveLength = std::stod(argv[2]); - auto curve = CurveReader::readCurveInfo(inputCSV); - - //Construct BSpline2d object - SplineInterp::BSpline2d serialBSP; - if (curve.x.size() == 2) { - serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); - } else { - serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); - } - - std::vector ctrlPtsX, ctrlPtsY, knots, weight; - int order; - - serialBSP.x.getpara(order, ctrlPtsX, knots, weight); - serialBSP.y.getpara(order, ctrlPtsY, knots, weight); - - BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); - - auto intView = Kokkos::create_mirror_view(kokkosBSP.getOrder()); - Kokkos::deep_copy(intView, kokkosBSP.getOrder()); - //Testing the order initialization - double diff = std::fabs(order - intView(0)); - if (diff > EPSILON) { - std::cout << "Order difference : " << diff << std::endl; - std::cout << "Serial: " << order << " Kokkos: " << intView(0) << std::endl; - retVal = 1; - } - - auto double2DView = Kokkos::create_mirror_view(kokkosBSP.getCtrlPts()); - Kokkos::deep_copy(double2DView, kokkosBSP.getCtrlPts()); - - //Testing ctrlPts initialization - double xDiff, yDiff; - for (int i = 0; i < ctrlPtsX.size(); i++) { - xDiff = std::fabs(ctrlPtsX[i] - double2DView(i, 0)); - yDiff = std::fabs(ctrlPtsY[i] - double2DView(i, 1)); - if (xDiff > EPSILON || yDiff > EPSILON) { - std::cout << "CtrlPts difference: x = " << xDiff << " y = " << yDiff << std::endl; - std::cout << "Serial: " << ctrlPtsX[i] << ", " << ctrlPtsY[i] << std::endl; - std::cout << "Kokkos: " << double2DView(i, 0) << ", " << double2DView(i, 1) << std::endl; - retVal = 1; - } - } - - //Test knots initialization - auto doubleView = Kokkos::create_mirror_view(kokkosBSP.getKnots()); - Kokkos::deep_copy(doubleView, kokkosBSP.getKnots()); - for (int i = 0; i < knots.size(); i++) { - diff = std::fabs(knots[i] - doubleView(i)); - if (diff > EPSILON) { - std::cout << "Knots difference: " << diff << std::endl; - std::cout << "Serial: " << knots[i] << std::endl; - std::cout << "Kokkos: " << doubleView(i) << std::endl; - retVal = 1; - } - } - - //Test 1st deriv coef initialization - Kokkos::View coef ("getCPCoe2", kokkosBSP.getCP1stD().extent(0)); - - coef = kokkosBSP.getCP1stD(); - - auto mv_coef = Kokkos::create_mirror_view(coef); - - Kokkos::deep_copy(mv_coef, coef); - - std::vector serialCoefX = serialBSP.x.getCtrlPts_1st(); - std::vector serialCoefY = serialBSP.y.getCtrlPts_1st(); - - for (int i = 0; i < serialCoefX.size(); i++) { - double diffX = std::fabs(serialCoefX[i] - mv_coef(i, 0)); - double diffY = std::fabs(serialCoefY[i] - mv_coef(i, 1)); - if (diffX > EPSILON || diffY > EPSILON) { - std::cout << "diffX: " << diffX << std::endl; - std::cout << "diffY: " << diffY << std::endl; - std::cout << "Serial 1st coef: " << serialCoefX[i] << ", " << serialCoefY[i] << std::endl; - std::cout << "Kokkos 1st coef: " << mv_coef(i, 0)<< ", " << mv_coef(i, 1) << std::endl; - retVal = 1; - } - - } - - Kokkos::Viewcoef2 ("getCPCoe2", kokkosBSP.getCP2ndD().extent(0)); - coef2 = kokkosBSP.getCP2ndD(); - - mv_coef = Kokkos::create_mirror_view(coef2); - - Kokkos::deep_copy(mv_coef, coef2); - - serialCoefX = serialBSP.x.getCtrlPts_2nd(); - serialCoefY = serialBSP.y.getCtrlPts_2nd(); - for (int i = 0; i < serialCoefX.size(); i++) { - double diffX = std::fabs(serialCoefX[i] - mv_coef(i, 0)); - double diffY = std::fabs(serialCoefY[i] - mv_coef(i, 1)); - if (diffX > EPSILON || diffY > EPSILON) { - std::cout << "diffX: " << diffX << std::endl; - std::cout << "diffY: " << diffY << std::endl; - std::cout << "Serial 2nd coef: " << serialCoefX[i] << ", " << serialCoefY[i] << std::endl; - std::cout << "Kokkos 2nd coef: " << mv_coef(i, 0)<< ", " << mv_coef(i, 1) << std::endl; - retVal = 1; - } - } + std::vector ctrlPtsX, ctrlPtsY, knots, weight; + int order; + + serialBSP.x.getpara(order, ctrlPtsX, knots, weight); + serialBSP.y.getpara(order, ctrlPtsY, knots, weight); + + BSplineKokkos2D kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); + + auto intView = Kokkos::create_mirror_view(kokkosBSP.getOrder()); + Kokkos::deep_copy(intView, kokkosBSP.getOrder()); + //Testing the order initialization + double diff = std::fabs(order - intView(0)); + if (diff > EPSILON) { + std::cout << "Order difference : " << diff << std::endl; + std::cout << "Serial: " << order << " Kokkos: " << intView(0) << std::endl; + retVal = 1; + } + + auto double2DView = Kokkos::create_mirror_view(kokkosBSP.getCtrlPts()); + Kokkos::deep_copy(double2DView, kokkosBSP.getCtrlPts()); + + //Testing ctrlPts initialization + double xDiff, yDiff; + for (int i = 0; i < ctrlPtsX.size(); i++) { + xDiff = std::fabs(ctrlPtsX[i] - double2DView(i, 0)); + yDiff = std::fabs(ctrlPtsY[i] - double2DView(i, 1)); + if (xDiff > EPSILON || yDiff > EPSILON) { + std::cout << "CtrlPts difference: x = " << xDiff << " y = " << yDiff << std::endl; + std::cout << "Serial: " << ctrlPtsX[i] << ", " << ctrlPtsY[i] << std::endl; + std::cout << "Kokkos: " << double2DView(i, 0) << ", " << double2DView(i, 1) << std::endl; + retVal = 1; + } + } + + //Test knots initialization + auto doubleView = Kokkos::create_mirror_view(kokkosBSP.getKnots()); + Kokkos::deep_copy(doubleView, kokkosBSP.getKnots()); + for (int i = 0; i < knots.size(); i++) { + diff = std::fabs(knots[i] - doubleView(i)); + if (diff > EPSILON) { + std::cout << "Knots difference: " << diff << std::endl; + std::cout << "Serial: " << knots[i] << std::endl; + std::cout << "Kokkos: " << doubleView(i) << std::endl; + retVal = 1; + } + } + + //Test 1st deriv coef initialization + Kokkos::View coef ("getCPCoe2", kokkosBSP.getCP1stD().extent(0)); + coef = kokkosBSP.getCP1stD(); + auto mv_coef = Kokkos::create_mirror_view(coef); + + Kokkos::deep_copy(mv_coef, coef); + std::vector serialCoefX = serialBSP.x.getCtrlPts_1st(); + std::vector serialCoefY = serialBSP.y.getCtrlPts_1st(); + + for (int i = 0; i < serialCoefX.size(); i++) { + double diffX = std::fabs(serialCoefX[i] - mv_coef(i, 0)); + double diffY = std::fabs(serialCoefY[i] - mv_coef(i, 1)); + if (diffX > EPSILON || diffY > EPSILON) { + std::cout << "diffX: " << diffX << std::endl; + std::cout << "diffY: " << diffY << std::endl; + std::cout << "Serial 1st coef: " << serialCoefX[i] << ", " << serialCoefY[i] << std::endl; + std::cout << "Kokkos 1st coef: " << mv_coef(i, 0)<< ", " << mv_coef(i, 1) << std::endl; + retVal = 1; + } } - Kokkos::finalize(); - return retVal; + + Kokkos::Viewcoef2 ("getCPCoe2", kokkosBSP.getCP2ndD().extent(0)); + coef2 = kokkosBSP.getCP2ndD(); + mv_coef = Kokkos::create_mirror_view(coef2); + + Kokkos::deep_copy(mv_coef, coef2); + + serialCoefX = serialBSP.x.getCtrlPts_2nd(); + serialCoefY = serialBSP.y.getCtrlPts_2nd(); + for (int i = 0; i < serialCoefX.size(); i++) { + double diffX = std::fabs(serialCoefX[i] - mv_coef(i, 0)); + double diffY = std::fabs(serialCoefY[i] - mv_coef(i, 1)); + if (diffX > EPSILON || diffY > EPSILON) { + std::cout << "diffX: " << diffX << std::endl; + std::cout << "diffY: " << diffY << std::endl; + std::cout << "Serial 2nd coef: " << serialCoefX[i] << ", " << serialCoefY[i] << std::endl; + std::cout << "Kokkos 2nd coef: " << mv_coef(i, 0)<< ", " << mv_coef(i, 1) << std::endl; + retVal = 1; + } + } + + } + Kokkos::finalize(); + return retVal; } diff --git a/testSplineKokkosBase.cpp b/testSplineKokkosBase.cpp index dd35ca8..37a78f6 100644 --- a/testSplineKokkosBase.cpp +++ b/testSplineKokkosBase.cpp @@ -15,199 +15,193 @@ template void printDView(Kokkos::View& dView) { - auto host_dView = Kokkos::create_mirror_view(dView); - Kokkos::deep_copy(host_dView, dView); - for (int i = 0; i < host_dView.extent(0); i++) { - std::cout << host_dView(i) << std::endl; - } + auto host_dView = Kokkos::create_mirror_view(dView); + Kokkos::deep_copy(host_dView, dView); + for (int i = 0; i < host_dView.extent(0); i++) { + std::cout << host_dView(i) << std::endl; + } } template void printIView(Kokkos::View& iView) { - auto host_iView = Kokkos::create_mirror_view(iView); - Kokkos::deep_copy(host_iView, iView); - for (int i = 0; i < host_iView.extent(0); i++) { - std::cout << host_iView(i) << std::endl; - } + auto host_iView = Kokkos::create_mirror_view(iView); + Kokkos::deep_copy(host_iView, iView); + for (int i = 0; i < host_iView.extent(0); i++) { + std::cout << host_iView(i) << std::endl; + } } template void printSpline(BSplineKokkos spline) { - std::cout << "Spline content" << std::endl; - Kokkos::View dView = spline.getCtrlPts(); - std::cout << "CtrlPts" << std::endl; - printDView(dView); - Kokkos::View iView = spline.getCPOffset(); - std::cout << "CtrlPts Offset" << std::endl; - printIView(iView); - dView = spline.getKnots(); - std::cout << "Knots" << std::endl; - printDView(dView); - iView = spline.getKnotsOffset(); - std::cout << "Knots Offset" << std::endl; - printIView(iView); - iView = spline.getOrder(); - std::cout << "Order" << std::endl; - printIView(iView); + std::cout << "Spline content" << std::endl; + Kokkos::View dView = spline.getCtrlPts(); + std::cout << "CtrlPts" << std::endl; + printDView(dView); + Kokkos::View iView = spline.getCPOffset(); + std::cout << "CtrlPts Offset" << std::endl; + printIView(iView); + dView = spline.getKnots(); + std::cout << "Knots" << std::endl; + printDView(dView); + iView = spline.getKnotsOffset(); + std::cout << "Knots Offset" << std::endl; + printIView(iView); + iView = spline.getOrder(); + std::cout << "Order" << std::endl; + printIView(iView); } void printVector(const std::string& name, std::vector& vector) { - std::cout << name << ": " << vector.size() << std::endl; - for (int i = 0; i < vector.size(); i++) { - std::cout << vector[i] << std::endl; - } + std::cout << name << ": " << vector.size() << std::endl; + for (int i = 0; i < vector.size(); i++) { + std::cout << vector[i] << std::endl; + } } int main(int argc, char* argv[]) { - Kokkos::initialize(argc, argv); - { - //Check for what memory space we should use - //Sticking to just cuda space or host space for now - - #ifdef KOKKOS_ENABLE_CUDA - #define MemSpace Kokkos::CudaSpace - #endif - #ifndef MemSpace - #define MemSpace Kokkos::HostSpace - #endif - - using ExecutionSpace = MemSpace::execution_space; - //We will try to test with dummy data for BSplineKokkos creation - std::vector dummyCtrlPtsX{2.14, 3.98, 1.56, 9.10, 11.87}; - std::vector dummyCtrlPtsY{7.928, 12.18, 9.17, 6.67, 12.78}; - std::vector dummyKnotsX{5.99, 8.98, 17.71, 21.1, 2.154, 9.17, 6.32}; - //std::vector dummyKnotsY{2.85, 1.16, 0.82, 1.89, 9.82, 12.0, 7.19}; - int dOrder = 2; - //std::vector dummyWeights{0.87, 0.125, 0.03}; - //Initialize 1 Kokkos Spline - BSplineKokkos ex1(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX); - - //Check if we actually initialized with correct values - std::cout << "ex1" << std::endl; - printSpline(ex1); - std::vector> splineList; - splineList.push_back(ex1); - - //Test constructor that takes in multiple BSplineKokkos objects - dummyCtrlPtsX.assign({1.20, 12.91, 7.11}); - dummyCtrlPtsY.assign({3.31, 7.89, 9.12}); - dummyKnotsX.assign({2.18, 5.56, 3.18, 16.15}); - //dummyKnotsY.assign({1.971,4.12, 8.192, 12.11}); - dOrder = 3; - //dummyWeights.assign({0.19, 0.27}); - BSplineKokkos ex2(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX); - splineList.push_back(ex2); - std::cout << "ex2" << std::endl; - printSpline(ex2); - - dummyCtrlPtsX.assign({18.29, 12.12, 5.92, 7.182, 1.16}); - dummyCtrlPtsY.assign({4.72, 5.78, 9.12, 1.29, 10.2}); - dummyKnotsX.assign({4.34, 29.3, 18.7, 15.14, 16.87, 9.99}); - dOrder = 5; - std::cout << "\t\tSTART OF MULTISPLINE CREATION" << std::endl; - BSplineKokkos ex3(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX); - splineList.push_back(ex3); - std::cout << "ex3" << std::endl; - printSpline(ex3); - - BSplineKokkos fromList(splineList); - - std::cout << "Spline created from list of splines" << std::endl; - printSpline(fromList); - - std::cout << "\n\nChecking derivative calculation against serial version" << std::endl; - std::cout << "Number of commandline arguments: " << argc << std::endl; - for (int i = 0; i < argc; i++) { - std::cout << argv[i] << std::endl; - } - if (argc != 3) { - //Check for the arguments needed - std::cerr<<"Input arguments: " << std::endl; - std::cerr << "input csv need these columns: "; - std::cerr << "x,y,z,isOnCurve,angle,isMdlVtx" << std::endl; - return 1; - } - - //Set up before using curve reader - std::string inputCSV = argv[1]; - int extensionPos = inputCSV.rfind("."); - int slashPos = inputCSV.rfind("/"); - std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); - double expectedCurveLength = std::stod(argv[2]); - auto curve = CurveReader::readCurveInfo(inputCSV); - - //Construct BSpline2d object - SplineInterp::BSpline2d serialBSP; - if (curve.x.size() == 2) { - serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); - } - else { - serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); - } - - //Get the parameters and print the spline we initialized - std::vector ctrlPtsX, ctrlPtsY, knots, weight; - int order; - serialBSP.x.getpara(order, ctrlPtsX, knots, weight); - std::cout << "x component of the spline" << std::endl; - std::cout << "order: " << order << std::endl; - printVector("ctrlPtsX", ctrlPtsX); - printVector("knots", knots); - printVector("weight", weight); - serialBSP.y.getpara(order, ctrlPtsY, knots, weight); - std::cout << "y component of the spline" << std::endl; - std::cout << "order: " << order << std::endl; - printVector("ctrlPtsY", ctrlPtsY); - printVector("knots", knots); - printVector("weight", weight); - - //Now that we ensured that serial BSpline is created correctly we will now feed these data to our BSpline Kokkos Object - BSplineKokkos kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); - printSpline(kokkosBSP); - - - //We can now test taking the first derivative - std::cout << "----Serial 1st derivative----" << std::endl; - for (int i = 0; i < ctrlPtsX.size(); i++) { - std::cout <<"Point: " << ctrlPtsX[i] << ", "; - std::cout << ctrlPtsY[i] << std::endl; - } - std::cout << "1st derivative, input x = 0: " << serialBSP.x.evalFirstDeriv(0) << ", " << serialBSP.y.evalFirstDeriv(0) << std::endl; - std::cout << "1st derivative, input x = 1: " << serialBSP.x.evalFirstDeriv(1) << ", " << serialBSP.y.evalFirstDeriv(1) << std::endl; - - std::cout << "----Kokkos 1st derivative----" << std::endl; - //Get and copy the control points here so we could print them - Kokkos::View dView = kokkosBSP.getCtrlPts(); - auto host_dView = Kokkos::create_mirror_view(dView); - Kokkos::deep_copy(host_dView, dView); - for (int i = 1; i < host_dView.extent(0); i+=2) { - std::cout <<"Point: " << host_dView(i-1) << ", " << host_dView(i) << std::endl; - } - std::cout << "1st derivative, input x = 0: " << kokkosBSP.eval1stDeriv({0}, 0)[0] << std::endl; - - std::cout << "1st derivative, input x = 1: " << kokkosBSP.eval1stDeriv({1}, 0)[0] << std::endl; - - std::cout << "----Serial 2nd derivative----" << std::endl; - double x2ndD = serialBSP.x.evalSecondDeriv(0); - double y2ndD = serialBSP.y.evalSecondDeriv(0); - std::cout << "2nd derivative, input x = 0: " << x2ndD << ", " << y2ndD << std::endl; - - x2ndD = serialBSP.x.evalSecondDeriv(1); - y2ndD = serialBSP.y.evalSecondDeriv(1); - std::cout << "2nd derivative, input x = 1: " << x2ndD << ", " << y2ndD << std::endl; - - std::cout << "----Kokkos 2nd derivative----" << std::endl; - //Get and copy the control points here so we could print them - dView = kokkosBSP.getCtrlPts(); - host_dView = Kokkos::create_mirror_view(dView); - Kokkos::deep_copy(host_dView, dView); - for (int i = 1; i < host_dView.extent(0); i+=2) { - std::cout <<"Point: " << host_dView(i-1) << ", " << host_dView(i) << std::endl; - } - std::cout << "2nd derivative, input x = 0: " << kokkosBSP.eval2ndDeriv(0, 0) << std::endl; - - std::cout << "2nd derivative, input x = 1: " << kokkosBSP.eval2ndDeriv(1, 0) << std::endl; + Kokkos::initialize(argc, argv); + { + //Check for what memory space we should use + //Sticking to just cuda space or host space for now + + #ifdef KOKKOS_ENABLE_CUDA + #define MemSpace Kokkos::CudaSpace + #endif + #ifndef MemSpace + #define MemSpace Kokkos::HostSpace + #endif + + using ExecutionSpace = MemSpace::execution_space; + //We will try to test with dummy data for BSplineKokkos creation + std::vector dummyCtrlPtsX{2.14, 3.98, 1.56, 9.10, 11.87}; + std::vector dummyCtrlPtsY{7.928, 12.18, 9.17, 6.67, 12.78}; + std::vector dummyKnotsX{5.99, 8.98, 17.71, 21.1, 2.154, 9.17, 6.32}; + int dOrder = 2; + //Initialize 1 Kokkos Spline + BSplineKokkos ex1(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX); + + //Check if we actually initialized with correct values + std::cout << "ex1" << std::endl; + printSpline(ex1); + std::vector> splineList; + splineList.push_back(ex1); + + //Test constructor that takes in multiple BSplineKokkos objects + dummyCtrlPtsX.assign({1.20, 12.91, 7.11}); + dummyCtrlPtsY.assign({3.31, 7.89, 9.12}); + dummyKnotsX.assign({2.18, 5.56, 3.18, 16.15}); + dOrder = 3; + BSplineKokkos ex2(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX); + splineList.push_back(ex2); + std::cout << "ex2" << std::endl; + printSpline(ex2); + + dummyCtrlPtsX.assign({18.29, 12.12, 5.92, 7.182, 1.16}); + dummyCtrlPtsY.assign({4.72, 5.78, 9.12, 1.29, 10.2}); + dummyKnotsX.assign({4.34, 29.3, 18.7, 15.14, 16.87, 9.99}); + dOrder = 5; + std::cout << "\t\tSTART OF MULTISPLINE CREATION" << std::endl; + BSplineKokkos ex3(dOrder, dummyCtrlPtsX, dummyCtrlPtsY, dummyKnotsX); + splineList.push_back(ex3); + std::cout << "ex3" << std::endl; + printSpline(ex3); + + BSplineKokkos fromList(splineList); + + std::cout << "Spline created from list of splines" << std::endl; + printSpline(fromList); + + std::cout << "\n\nChecking derivative calculation against serial version" << std::endl; + std::cout << "Number of commandline arguments: " << argc << std::endl; + for (int i = 0; i < argc; i++) { + std::cout << argv[i] << std::endl; + } + if (argc != 3) { + //Check for the arguments needed + std::cerr<<"Input arguments: " << std::endl; + std::cerr << "input csv need these columns: "; + std::cerr << "x,y,z,isOnCurve,angle,isMdlVtx" << std::endl; + return 1; + } + //Set up before using curve reader + std::string inputCSV = argv[1]; + int extensionPos = inputCSV.rfind("."); + int slashPos = inputCSV.rfind("/"); + std::string fileNameNoExt = inputCSV.substr(slashPos+1, extensionPos); + double expectedCurveLength = std::stod(argv[2]); + auto curve = CurveReader::readCurveInfo(inputCSV); + + //Construct BSpline2d object + SplineInterp::BSpline2d serialBSP; + if (curve.x.size() == 2) { + serialBSP = SplineInterp::attach_piecewise_linear_curve(curve.x, curve.y); } - Kokkos::finalize(); + else { + serialBSP = SplineInterp::fitCubicSplineToPoints(curve.x, curve.y); + } + + //Get the parameters and print the spline we initialized + std::vector ctrlPtsX, ctrlPtsY, knots, weight; + int order; + serialBSP.x.getpara(order, ctrlPtsX, knots, weight); + std::cout << "x component of the spline" << std::endl; + std::cout << "order: " << order << std::endl; + printVector("ctrlPtsX", ctrlPtsX); + printVector("knots", knots); + printVector("weight", weight); + serialBSP.y.getpara(order, ctrlPtsY, knots, weight); + std::cout << "y component of the spline" << std::endl; + std::cout << "order: " << order << std::endl; + printVector("ctrlPtsY", ctrlPtsY); + printVector("knots", knots); + printVector("weight", weight); + + //Now that we ensured that serial BSpline is created correctly we will now feed these data to our BSpline Kokkos Object + BSplineKokkos kokkosBSP(order, ctrlPtsX, ctrlPtsY, knots); + printSpline(kokkosBSP); + + //We can now test taking the first derivative + std::cout << "----Serial 1st derivative----" << std::endl; + for (int i = 0; i < ctrlPtsX.size(); i++) { + std::cout <<"Point: " << ctrlPtsX[i] << ", "; + std::cout << ctrlPtsY[i] << std::endl; + } + std::cout << "1st derivative, input x = 0: " << serialBSP.x.evalFirstDeriv(0) << ", " << serialBSP.y.evalFirstDeriv(0) << std::endl; + std::cout << "1st derivative, input x = 1: " << serialBSP.x.evalFirstDeriv(1) << ", " << serialBSP.y.evalFirstDeriv(1) << std::endl; + + std::cout << "----Kokkos 1st derivative----" << std::endl; + //Get and copy the control points here so we could print them + Kokkos::View dView = kokkosBSP.getCtrlPts(); + auto host_dView = Kokkos::create_mirror_view(dView); + Kokkos::deep_copy(host_dView, dView); + for (int i = 1; i < host_dView.extent(0); i+=2) { + std::cout <<"Point: " << host_dView(i-1) << ", " << host_dView(i) << std::endl; + } + std::cout << "1st derivative, input x = 0: " << kokkosBSP.eval1stDeriv({0}, 0)[0] << std::endl; + + std::cout << "1st derivative, input x = 1: " << kokkosBSP.eval1stDeriv({1}, 0)[0] << std::endl; + std::cout << "----Serial 2nd derivative----" << std::endl; + double x2ndD = serialBSP.x.evalSecondDeriv(0); + double y2ndD = serialBSP.y.evalSecondDeriv(0); + std::cout << "2nd derivative, input x = 0: " << x2ndD << ", " << y2ndD << std::endl; + + x2ndD = serialBSP.x.evalSecondDeriv(1); + y2ndD = serialBSP.y.evalSecondDeriv(1); + std::cout << "2nd derivative, input x = 1: " << x2ndD << ", " << y2ndD << std::endl; + + std::cout << "----Kokkos 2nd derivative----" << std::endl; + //Get and copy the control points here so we could print them + dView = kokkosBSP.getCtrlPts(); + host_dView = Kokkos::create_mirror_view(dView); + Kokkos::deep_copy(host_dView, dView); + for (int i = 1; i < host_dView.extent(0); i+=2) { + std::cout <<"Point: " << host_dView(i-1) << ", " << host_dView(i) << std::endl; + } + std::cout << "2nd derivative, input x = 0: " << kokkosBSP.eval2ndDeriv(0, 0) << std::endl; + + std::cout << "2nd derivative, input x = 1: " << kokkosBSP.eval2ndDeriv(1, 0) << std::endl; + + } + Kokkos::finalize(); }