From ba3ea2af404e804c6b8659d4ee21c070615cc813 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 3 Feb 2025 13:02:36 -0500 Subject: [PATCH 01/52] Fix spacing in Enzyme basic examples. --- examples/Enzyme/Library/library.cpp | 2 +- examples/Enzyme/Library/main.cpp | 24 ++++++++++++------------ examples/Enzyme/Standalone/main.cpp | 22 +++++++++++----------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/examples/Enzyme/Library/library.cpp b/examples/Enzyme/Library/library.cpp index 6ff34da7a..f801bd8ab 100644 --- a/examples/Enzyme/Library/library.cpp +++ b/examples/Enzyme/Library/library.cpp @@ -1,3 +1,3 @@ double square(double x) { - return x * x; + return x * x; } diff --git a/examples/Enzyme/Library/main.cpp b/examples/Enzyme/Library/main.cpp index e0aef4ecd..c97e81646 100644 --- a/examples/Enzyme/Library/main.cpp +++ b/examples/Enzyme/Library/main.cpp @@ -5,16 +5,16 @@ double __enzyme_autodiff(double (*)(double), ...); int main() { - int fail = 0; - double sq = square(5.0); - double dsq = __enzyme_autodiff(square, 5.0); - - std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; - if (std::abs(dsq - 10.0) > std::numeric_limits::epsilon()) - { - fail++; - std::cout << "Result incorrect\n"; - } - std::cout << "Status: " << fail << "\n"; - return fail; + int fail = 0; + double sq = square(5.0); + double dsq = __enzyme_autodiff(square, 5.0); + + std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; + if (std::abs(dsq - 10.0) > std::numeric_limits::epsilon()) + { + fail++; + std::cout << "Result incorrect\n"; + } + std::cout << "Status: " << fail << "\n"; + return fail; } diff --git a/examples/Enzyme/Standalone/main.cpp b/examples/Enzyme/Standalone/main.cpp index c9b81ef05..f9a4d8e22 100644 --- a/examples/Enzyme/Standalone/main.cpp +++ b/examples/Enzyme/Standalone/main.cpp @@ -2,12 +2,12 @@ #include double square(double x) { - return x * x; + return x * x; } double __enzyme_autodiff(double(*)(double), ...); double dsquare(double x) { - return __enzyme_autodiff(square, x); + return __enzyme_autodiff(square, x); } double sq = square(5.0); @@ -15,13 +15,13 @@ double dsq = dsquare(5.0); int main() { - int fail = 0; - std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; - if (std::abs(dsq - 10.0) > std::numeric_limits::epsilon()) - { - fail++; - std::cout << "Result incorrect\n"; - } - std::cout << "Status: " << fail << "\n"; - return fail; + int fail = 0; + std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; + if (std::abs(dsq - 10.0) > std::numeric_limits::epsilon()) + { + fail++; + std::cout << "Result incorrect\n"; + } + std::cout << "Status: " << fail << "\n"; + return fail; } From 2904eff449fd02eb87ebf07296163c51642d0869 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 3 Feb 2025 13:11:00 -0500 Subject: [PATCH 02/52] SparseMatrix directory. --- examples/SparseTest/SparseTest.cpp | 2 +- src/LinearAlgebra/CMakeLists.txt | 7 +------ src/LinearAlgebra/SparseMatrix/CMakeLists.txt | 6 ++++++ src/LinearAlgebra/{ => SparseMatrix}/COO_Matrix.hpp | 0 src/ModelEvaluator.hpp | 4 ++-- 5 files changed, 10 insertions(+), 9 deletions(-) create mode 100644 src/LinearAlgebra/SparseMatrix/CMakeLists.txt rename src/LinearAlgebra/{ => SparseMatrix}/COO_Matrix.hpp (100%) diff --git a/examples/SparseTest/SparseTest.cpp b/examples/SparseTest/SparseTest.cpp index c7c07195d..9859e31c9 100644 --- a/examples/SparseTest/SparseTest.cpp +++ b/examples/SparseTest/SparseTest.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include int main(int argc, char const *argv[]) { diff --git a/src/LinearAlgebra/CMakeLists.txt b/src/LinearAlgebra/CMakeLists.txt index b51d669ec..eeda5e797 100644 --- a/src/LinearAlgebra/CMakeLists.txt +++ b/src/LinearAlgebra/CMakeLists.txt @@ -1,7 +1,2 @@ -add_library(SparseMatrix INTERFACE) -include_directories(SparseMatrix INTERFACE ${CMAKE_CURRENT_LIST_DIR}) - -add_library(GRIDKIT::SparseMatrix ALIAS SparseMatrix) - - +add_subdirectory(SparseMatrix) diff --git a/src/LinearAlgebra/SparseMatrix/CMakeLists.txt b/src/LinearAlgebra/SparseMatrix/CMakeLists.txt new file mode 100644 index 000000000..ddb185489 --- /dev/null +++ b/src/LinearAlgebra/SparseMatrix/CMakeLists.txt @@ -0,0 +1,6 @@ + +add_library(SparseMatrix INTERFACE) +include_directories(SparseMatrix INTERFACE ${CMAKE_CURRENT_LIST_DIR}) + +add_library(GRIDKIT::SparseMatrix ALIAS SparseMatrix) + diff --git a/src/LinearAlgebra/COO_Matrix.hpp b/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp similarity index 100% rename from src/LinearAlgebra/COO_Matrix.hpp rename to src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp diff --git a/src/ModelEvaluator.hpp b/src/ModelEvaluator.hpp index f502acf25..79aa83b45 100644 --- a/src/ModelEvaluator.hpp +++ b/src/ModelEvaluator.hpp @@ -62,7 +62,7 @@ #include #include -#include +#include namespace ModelLib { @@ -154,4 +154,4 @@ namespace ModelLib } // namespace ModelLib -#endif // _MODEL_EVALUATOR_HPP_ \ No newline at end of file +#endif // _MODEL_EVALUATOR_HPP_ From 8254ce28a0095cf0386daca1facf84a67e65a78a Mon Sep 17 00:00:00 2001 From: Asher Mancinelli Date: Thu, 3 Mar 2022 08:01:10 +0600 Subject: [PATCH 03/52] Add preliminary Enzyme support --- CMakeLists.txt | 3 +++ Examples/Enzyme/CMakeLists.txt | 2 ++ Examples/Enzyme/Library/CMakeLists.txt | 4 ++++ Examples/Enzyme/Library/library.cpp | 3 +++ Examples/Enzyme/Library/library.hpp | 2 ++ Examples/Enzyme/Library/main.cpp | 10 ++++++++++ Examples/Enzyme/Standalone/CMakeLists.txt | 4 ++++ Examples/Enzyme/Standalone/main.cpp | 17 +++++++++++++++++ cmake/FindSuiteSparse.cmake | 6 +++--- 9 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 Examples/Enzyme/CMakeLists.txt create mode 100644 Examples/Enzyme/Library/CMakeLists.txt create mode 100644 Examples/Enzyme/Library/library.cpp create mode 100644 Examples/Enzyme/Library/library.hpp create mode 100644 Examples/Enzyme/Library/main.cpp create mode 100644 Examples/Enzyme/Standalone/CMakeLists.txt create mode 100644 Examples/Enzyme/Standalone/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fbba2cb6..5965b6da6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,6 +130,9 @@ if(GRIDKIT_ENABLE_SUNDIALS) find_package(SUNDIALS 7.0.0 REQUIRED CONFIG PATHS ${SUNDIALS_DIR} ${SUNDIALS_DIR}/lib/cmake/sundials) + if("${SUNDIALS_VERSION}" VERSION_LESS "5.5.0") + message(FATAL_ERROR "GridKit requires SUNDIALS >= 5.5.0, got ${SUNDIALS_VERSION}") + endif() message(STATUS "SUNDIALS configuration found: ${SUNDIALS_CONFIG}") endif() if(GRIDKIT_ENABLE_SUNDIALS_SPARSE) diff --git a/Examples/Enzyme/CMakeLists.txt b/Examples/Enzyme/CMakeLists.txt new file mode 100644 index 000000000..794ec850c --- /dev/null +++ b/Examples/Enzyme/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(Standalone) +add_subdirectory(Library) diff --git a/Examples/Enzyme/Library/CMakeLists.txt b/Examples/Enzyme/Library/CMakeLists.txt new file mode 100644 index 000000000..afc6d1e76 --- /dev/null +++ b/Examples/Enzyme/Library/CMakeLists.txt @@ -0,0 +1,4 @@ +enzyme_add_executable( + NAME LibraryEnzymeCheck + SOURCES main.cpp library.cpp + ) diff --git a/Examples/Enzyme/Library/library.cpp b/Examples/Enzyme/Library/library.cpp new file mode 100644 index 000000000..42e2436d5 --- /dev/null +++ b/Examples/Enzyme/Library/library.cpp @@ -0,0 +1,3 @@ +int square(int x) { + return x * x; +} diff --git a/Examples/Enzyme/Library/library.hpp b/Examples/Enzyme/Library/library.hpp new file mode 100644 index 000000000..6874174a1 --- /dev/null +++ b/Examples/Enzyme/Library/library.hpp @@ -0,0 +1,2 @@ +#pragma once +int square(int x); diff --git a/Examples/Enzyme/Library/main.cpp b/Examples/Enzyme/Library/main.cpp new file mode 100644 index 000000000..1fd429bbf --- /dev/null +++ b/Examples/Enzyme/Library/main.cpp @@ -0,0 +1,10 @@ +#include "library.hpp" + +int __enzyme_autodiff(int (*)(int), ...); + +int main() { + int fail = 0; + if (__enzyme_autodiff(square, 5) != 25) + fail++; + return fail; +} diff --git a/Examples/Enzyme/Standalone/CMakeLists.txt b/Examples/Enzyme/Standalone/CMakeLists.txt new file mode 100644 index 000000000..ba099289c --- /dev/null +++ b/Examples/Enzyme/Standalone/CMakeLists.txt @@ -0,0 +1,4 @@ +enzyme_add_executable( + NAME StandaloneEnzymeCheck + SOURCES main.cpp + ) diff --git a/Examples/Enzyme/Standalone/main.cpp b/Examples/Enzyme/Standalone/main.cpp new file mode 100644 index 000000000..5b3a2348c --- /dev/null +++ b/Examples/Enzyme/Standalone/main.cpp @@ -0,0 +1,17 @@ +#include + +int foo(int x) { + return x * x; +} + +int __enzyme_autodiff(int(*)(int), ...); +int dfoo(int x) { + return __enzyme_autodiff(foo, x); +} + +int main() { + int fail = 0; + if (dfoo(5) != 25) + fail++; + return fail; +} diff --git a/cmake/FindSuiteSparse.cmake b/cmake/FindSuiteSparse.cmake index 5a1026935..550b55e54 100644 --- a/cmake/FindSuiteSparse.cmake +++ b/cmake/FindSuiteSparse.cmake @@ -123,15 +123,15 @@ if(SUITESPARSE_LIBRARY) endforeach(mod) else() if(NOT SUITESPARSE_ROOT_DIR) - message(STATUS "Suitesparse dir not found! Please provide correct filepath.") + message(FATAL_ERROR "Suitesparse dir not found! Please provide correct filepath.") set(SUITESPARSE_DIR ${SUITESPARSE_DIR} CACHE PATH "Path to Suitesparse installation root.") unset(SUITESPARSE_LIBRARY CACHE) unset(SUITESPARSE_INCLUDE_DIR CACHE) unset(SUITESPARSE_LIBRARY_DIR CACHE) elseif(NOT SUITESPARSE_LIBRARY) - message(STATUS "Suitesparse library not found! Please provide correct filepath.") + message(FATAL_ERROR "Suitesparse library not found! Please provide correct filepath.") endif() if(SUITESPARSE_ROOT_DIR AND NOT SUITESPARSE_INCLUDE_DIR) - message(STATUS "Suitesparse include dir not found! Please provide correct filepath.") + message(FATAL_ERROR "Suitesparse include dir not found! Please provide correct filepath.") endif() endif() From 8b50a7ee80cd8583d2a9ed075199d19b338f45e6 Mon Sep 17 00:00:00 2001 From: Asher Mancinelli Date: Thu, 3 Mar 2022 08:05:19 +0600 Subject: [PATCH 04/52] Use better naming conventions --- Examples/Enzyme/Standalone/main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Examples/Enzyme/Standalone/main.cpp b/Examples/Enzyme/Standalone/main.cpp index 5b3a2348c..5ee9a6cda 100644 --- a/Examples/Enzyme/Standalone/main.cpp +++ b/Examples/Enzyme/Standalone/main.cpp @@ -1,17 +1,17 @@ #include -int foo(int x) { +int square(int x) { return x * x; } int __enzyme_autodiff(int(*)(int), ...); -int dfoo(int x) { - return __enzyme_autodiff(foo, x); +int dsquare(int x) { + return __enzyme_autodiff(square, x); } int main() { int fail = 0; - if (dfoo(5) != 25) + if (dsquare(5) != 25) fail++; return fail; } From be8f2e822691b4e36b91d1788cf68d999854a7ae Mon Sep 17 00:00:00 2001 From: Asher Mancinelli Date: Mon, 7 Mar 2022 11:16:22 -0700 Subject: [PATCH 05/52] Apply suggestions from code review Co-authored-by: pelesh --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5965b6da6..a86d76e46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,8 +130,8 @@ if(GRIDKIT_ENABLE_SUNDIALS) find_package(SUNDIALS 7.0.0 REQUIRED CONFIG PATHS ${SUNDIALS_DIR} ${SUNDIALS_DIR}/lib/cmake/sundials) - if("${SUNDIALS_VERSION}" VERSION_LESS "5.5.0") - message(FATAL_ERROR "GridKit requires SUNDIALS >= 5.5.0, got ${SUNDIALS_VERSION}") + if("${SUNDIALS_VERSION}" VERSION_LESS "6.0.0") + message(FATAL_ERROR "GridKit requires SUNDIALS >= 6.0.0, got ${SUNDIALS_VERSION}") endif() message(STATUS "SUNDIALS configuration found: ${SUNDIALS_CONFIG}") endif() From 3d608a3d764331be80c5e39c35edc655ffa24efb Mon Sep 17 00:00:00 2001 From: Slaven Peles Date: Thu, 26 May 2022 12:50:07 -0400 Subject: [PATCH 06/52] More verbose tests for enzyme support. --- Examples/Enzyme/Library/CMakeLists.txt | 8 ++++---- Examples/Enzyme/Library/main.cpp | 17 +++++++++++++++-- Examples/Enzyme/Standalone/CMakeLists.txt | 2 ++ Examples/Enzyme/Standalone/main.cpp | 9 +++++++-- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/Examples/Enzyme/Library/CMakeLists.txt b/Examples/Enzyme/Library/CMakeLists.txt index afc6d1e76..dfd665ca0 100644 --- a/Examples/Enzyme/Library/CMakeLists.txt +++ b/Examples/Enzyme/Library/CMakeLists.txt @@ -1,4 +1,4 @@ -enzyme_add_executable( - NAME LibraryEnzymeCheck - SOURCES main.cpp library.cpp - ) +enzyme_add_executable(NAME libcheck SOURCES main.cpp library.cpp) +#install(TARGETS ${CMAKE_CURRENT_BINARY_DIR}/libcheck DESTINATION bin) + +add_test(NAME "libcheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/libcheck) diff --git a/Examples/Enzyme/Library/main.cpp b/Examples/Enzyme/Library/main.cpp index 1fd429bbf..e47ee535e 100644 --- a/Examples/Enzyme/Library/main.cpp +++ b/Examples/Enzyme/Library/main.cpp @@ -1,10 +1,23 @@ +#include #include "library.hpp" int __enzyme_autodiff(int (*)(int), ...); int main() { int fail = 0; - if (__enzyme_autodiff(square, 5) != 25) - fail++; + int sq = square(5); + int dersq = __enzyme_autodiff(square, 5); + + std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << dersq << "\n"; + if (__enzyme_autodiff(square, 5) != 10) + { + --fail; + // std::cout << "Incorrect result\n"; + } + if(fail < 0) + std::cout << "Result incorrect\n\n"; + else + std::cout << "Bingo!!\n\n"; + std:: cout << fail << "\n"; return fail; } diff --git a/Examples/Enzyme/Standalone/CMakeLists.txt b/Examples/Enzyme/Standalone/CMakeLists.txt index ba099289c..269bf1183 100644 --- a/Examples/Enzyme/Standalone/CMakeLists.txt +++ b/Examples/Enzyme/Standalone/CMakeLists.txt @@ -2,3 +2,5 @@ enzyme_add_executable( NAME StandaloneEnzymeCheck SOURCES main.cpp ) + + add_test(NAME "standalonecheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/StandaloneEnzymeCheck) diff --git a/Examples/Enzyme/Standalone/main.cpp b/Examples/Enzyme/Standalone/main.cpp index 5ee9a6cda..a57401b7b 100644 --- a/Examples/Enzyme/Standalone/main.cpp +++ b/Examples/Enzyme/Standalone/main.cpp @@ -9,9 +9,14 @@ int dsquare(int x) { return __enzyme_autodiff(square, x); } -int main() { +int sq = square(5); +int dsq = dsquare(5); + +int main() +{ int fail = 0; - if (dsquare(5) != 25) + std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << __enzyme_autodiff(square, 5) << "\n"; + if (dsq != 10) fail++; return fail; } From 536865e71d443e3ef4a17d18d32f2a9edf90eadd Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Tue, 29 Oct 2024 11:10:05 -0400 Subject: [PATCH 07/52] int --> double in Enzyme examples. --- Examples/Enzyme/Library/library.cpp | 2 +- Examples/Enzyme/Library/library.hpp | 2 +- Examples/Enzyme/Library/main.cpp | 21 +++++++++------------ Examples/Enzyme/Standalone/main.cpp | 19 ++++++++++++------- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/Examples/Enzyme/Library/library.cpp b/Examples/Enzyme/Library/library.cpp index 42e2436d5..6ff34da7a 100644 --- a/Examples/Enzyme/Library/library.cpp +++ b/Examples/Enzyme/Library/library.cpp @@ -1,3 +1,3 @@ -int square(int x) { +double square(double x) { return x * x; } diff --git a/Examples/Enzyme/Library/library.hpp b/Examples/Enzyme/Library/library.hpp index 6874174a1..b498a295b 100644 --- a/Examples/Enzyme/Library/library.hpp +++ b/Examples/Enzyme/Library/library.hpp @@ -1,2 +1,2 @@ #pragma once -int square(int x); +double square(double x); diff --git a/Examples/Enzyme/Library/main.cpp b/Examples/Enzyme/Library/main.cpp index e47ee535e..e0aef4ecd 100644 --- a/Examples/Enzyme/Library/main.cpp +++ b/Examples/Enzyme/Library/main.cpp @@ -1,23 +1,20 @@ #include +#include #include "library.hpp" -int __enzyme_autodiff(int (*)(int), ...); +double __enzyme_autodiff(double (*)(double), ...); int main() { int fail = 0; - int sq = square(5); - int dersq = __enzyme_autodiff(square, 5); + double sq = square(5.0); + double dsq = __enzyme_autodiff(square, 5.0); - std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << dersq << "\n"; - if (__enzyme_autodiff(square, 5) != 10) + std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; + if (std::abs(dsq - 10.0) > std::numeric_limits::epsilon()) { - --fail; - // std::cout << "Incorrect result\n"; + fail++; + std::cout << "Result incorrect\n"; } - if(fail < 0) - std::cout << "Result incorrect\n\n"; - else - std::cout << "Bingo!!\n\n"; - std:: cout << fail << "\n"; + std::cout << "Status: " << fail << "\n"; return fail; } diff --git a/Examples/Enzyme/Standalone/main.cpp b/Examples/Enzyme/Standalone/main.cpp index a57401b7b..c9b81ef05 100644 --- a/Examples/Enzyme/Standalone/main.cpp +++ b/Examples/Enzyme/Standalone/main.cpp @@ -1,22 +1,27 @@ #include +#include -int square(int x) { +double square(double x) { return x * x; } -int __enzyme_autodiff(int(*)(int), ...); -int dsquare(int x) { +double __enzyme_autodiff(double(*)(double), ...); +double dsquare(double x) { return __enzyme_autodiff(square, x); } -int sq = square(5); -int dsq = dsquare(5); +double sq = square(5.0); +double dsq = dsquare(5.0); int main() { int fail = 0; - std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << __enzyme_autodiff(square, 5) << "\n"; - if (dsq != 10) + std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; + if (std::abs(dsq - 10.0) > std::numeric_limits::epsilon()) + { fail++; + std::cout << "Result incorrect\n"; + } + std::cout << "Status: " << fail << "\n"; return fail; } From aa7b2c8755f254e7595daba238cd489113947cee Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Tue, 29 Oct 2024 13:41:16 -0400 Subject: [PATCH 08/52] Minor name changes for Enzyme tests. --- Examples/Enzyme/Library/CMakeLists.txt | 6 +++--- Examples/Enzyme/Standalone/CMakeLists.txt | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Examples/Enzyme/Library/CMakeLists.txt b/Examples/Enzyme/Library/CMakeLists.txt index dfd665ca0..78566c983 100644 --- a/Examples/Enzyme/Library/CMakeLists.txt +++ b/Examples/Enzyme/Library/CMakeLists.txt @@ -1,4 +1,4 @@ -enzyme_add_executable(NAME libcheck SOURCES main.cpp library.cpp) -#install(TARGETS ${CMAKE_CURRENT_BINARY_DIR}/libcheck DESTINATION bin) +enzyme_add_executable(NAME EnzymeLibCheck SOURCES main.cpp library.cpp) +#install(TARGETS ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibCheck DESTINATION bin) -add_test(NAME "libcheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/libcheck) +add_test(NAME "EnzymeLibCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibCheck) diff --git a/Examples/Enzyme/Standalone/CMakeLists.txt b/Examples/Enzyme/Standalone/CMakeLists.txt index 269bf1183..919d755e0 100644 --- a/Examples/Enzyme/Standalone/CMakeLists.txt +++ b/Examples/Enzyme/Standalone/CMakeLists.txt @@ -1,6 +1,6 @@ enzyme_add_executable( - NAME StandaloneEnzymeCheck + NAME EnzymeStandaloneCheck SOURCES main.cpp ) - add_test(NAME "standalonecheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/StandaloneEnzymeCheck) +add_test(NAME "EnzymeStandaloneCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneCheck) From b50827552ba40faea21bb89fabeb2c4dd54e7182 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Tue, 12 Nov 2024 13:33:03 -0500 Subject: [PATCH 09/52] Separate scalar and vector examples using Enzyme. --- Examples/Enzyme/Standalone/CMakeLists.txt | 12 ++- .../Standalone/{main.cpp => scalar.cpp} | 0 Examples/Enzyme/Standalone/vector.cpp | 93 +++++++++++++++++++ 3 files changed, 102 insertions(+), 3 deletions(-) rename Examples/Enzyme/Standalone/{main.cpp => scalar.cpp} (100%) create mode 100644 Examples/Enzyme/Standalone/vector.cpp diff --git a/Examples/Enzyme/Standalone/CMakeLists.txt b/Examples/Enzyme/Standalone/CMakeLists.txt index 919d755e0..e71df5101 100644 --- a/Examples/Enzyme/Standalone/CMakeLists.txt +++ b/Examples/Enzyme/Standalone/CMakeLists.txt @@ -1,6 +1,12 @@ enzyme_add_executable( - NAME EnzymeStandaloneCheck - SOURCES main.cpp + NAME EnzymeStandaloneScalarCheck + SOURCES scalar.cpp ) -add_test(NAME "EnzymeStandaloneCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneCheck) +enzyme_add_executable( + NAME EnzymeStandaloneVectorCheck + SOURCES vector.cpp + ) + +add_test(NAME "EnzymeStandaloneScalarCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneScalarCheck) +add_test(NAME "EnzymeStandaloneVectorCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneVectorCheck) diff --git a/Examples/Enzyme/Standalone/main.cpp b/Examples/Enzyme/Standalone/scalar.cpp similarity index 100% rename from Examples/Enzyme/Standalone/main.cpp rename to Examples/Enzyme/Standalone/scalar.cpp diff --git a/Examples/Enzyme/Standalone/vector.cpp b/Examples/Enzyme/Standalone/vector.cpp new file mode 100644 index 000000000..a891967e3 --- /dev/null +++ b/Examples/Enzyme/Standalone/vector.cpp @@ -0,0 +1,93 @@ +#include +#include +#include + +inline +double square(double x) { + return x * x; +} + +inline +double dsquare_ref(double x) { + return 2.0 * x; +} + +void square(std::vector x, std::vector& y) { + for (int idx = 0; idx < x.size(); ++idx) + { + y[idx] = square(x[idx]); + } +} + +void dsquare_ref(std::vector x, std::vector y, std::vector& dy) { + for (int idy = 0; idy < y.size(); ++idy) + { + for (int idx = 0; idx < x.size(); ++idx) + { + dy[idy*x.size()+idx] = dsquare_ref(x[idx]); + } + } +} + +double __enzyme_autodiff(double(*)(double), ...); +double dsquare(double x) { + return __enzyme_autodiff(square, x); +} + +void dsquare(std::vector x, std::vector y, std::vector& dy) { + for (int idy = 0; idy < y.size(); ++idy) + { + for (int idx = 0; idx < x.size(); ++idx) + { + dy[idy*x.size()+idx] = dsquare(x[idx]); + } + } +} + +int main() +{ + // Vector declarations + constexpr int N = 10; + std::vector x(N); + std::vector sq(N); + std::vector dsq(N*N); + std::vector dsq_ref(N*N); + + // Random input values + srand(time(NULL)); + for (int idx = 0; idx < x.size(); ++idx) + { + x[idx] = rand(); + } + + // Function evaluation + square(x, sq); + + // Reference Jacobian + dsquare_ref(x, sq, dsq_ref); + + // Enzyme Jacobian + dsquare(x, sq, dsq); + + // Check + int fail = 0; + bool verbose = false; + for (int idy = 0; idy < sq.size(); ++idy) + { + for (int idx = 0; idx < x.size(); ++idx) + { + int idxy = idy*x.size()+idx; + if (std::abs(dsq[idxy] - dsq_ref[idxy]) > std::numeric_limits::epsilon()) + { + fail++; + if (verbose) + { + std::cout << "Result incorrect at line = " << idy << ", column = " << idx << "\n"; + std::cout << "x = " << x[idx] << ", x^2 = " << sq[idx] << ", d(x^2)/dx = " << dsq[idxy] << "\n"; + } + } + } + } + std::cout << "Status: " << fail << "\n"; + return fail; +} From 119b57282d3fb673d561c4c8cfe6e75548bc0e43 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Tue, 19 Nov 2024 16:17:46 -0500 Subject: [PATCH 10/52] Jacobian of vector input function is diagonal. Using Enzyme in forward mode. --- Examples/Enzyme/Standalone/vector.cpp | 63 +++++++++++++++++---------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/Examples/Enzyme/Standalone/vector.cpp b/Examples/Enzyme/Standalone/vector.cpp index a891967e3..5f6ed82e5 100644 --- a/Examples/Enzyme/Standalone/vector.cpp +++ b/Examples/Enzyme/Standalone/vector.cpp @@ -2,52 +2,71 @@ #include #include +int enzyme_dupnoneed; +int enzyme_dup; +int enzyme_const; +void __enzyme_fwddiff(void*, ...); + inline -double square(double x) { +double square_scalar(double x) { return x * x; } inline -double dsquare_ref(double x) { +double dsquare_ref_scalar(double x) { return 2.0 * x; } -void square(std::vector x, std::vector& y) { - for (int idx = 0; idx < x.size(); ++idx) +void square(int N, double* x, double* y) { + for (int idx = 0; idx < N; ++idx) { - y[idx] = square(x[idx]); + y[idx] = square_scalar(x[idx]); } } -void dsquare_ref(std::vector x, std::vector y, std::vector& dy) { - for (int idy = 0; idy < y.size(); ++idy) +void dsquare_ref(int N, double* x, double* y, double* dy) { + for (int idy = 0; idy < N; ++idy) { - for (int idx = 0; idx < x.size(); ++idx) + for (int idx = 0; idx < N; ++idx) { - dy[idy*x.size()+idx] = dsquare_ref(x[idx]); + dy[idy*N+idx] = 0.0; + if (idx == idy) + dy[idy*N+idx] = dsquare_ref_scalar(x[idx]); } } } -double __enzyme_autodiff(double(*)(double), ...); -double dsquare(double x) { - return __enzyme_autodiff(square, x); -} - -void dsquare(std::vector x, std::vector y, std::vector& dy) { - for (int idy = 0; idy < y.size(); ++idy) +void dsquare(int N, double* x, double* y, double* dy) { + double* v = new double[N]; + double* d_y = new double[N]; + for (int idy = 0; idy < N; ++idy) { - for (int idx = 0; idx < x.size(); ++idx) + // Elementary vector for Jacobian-vector product + for (int idx = 0; idx < N; ++idx) + { + v[idx] = 0.0; + } + v[idy] = 1.0; + + // Autodiff + __enzyme_fwddiff((void*)square, enzyme_const, N, + enzyme_dup, x, v, + enzyme_dupnoneed, y, d_y); + + // Store result + for (int idx = 0; idx < N; ++idx) { - dy[idy*x.size()+idx] = dsquare(x[idx]); + dy[idy*N+idx] = d_y[idx]; } } + delete[] v; + delete[] d_y; } int main() { // Vector declarations - constexpr int N = 10; + constexpr int N = 2; std::vector x(N); std::vector sq(N); std::vector dsq(N*N); @@ -61,13 +80,13 @@ int main() } // Function evaluation - square(x, sq); + square(x.size(), x.data(), sq.data()); // Reference Jacobian - dsquare_ref(x, sq, dsq_ref); + dsquare_ref(x.size(), x.data(), sq.data(), dsq_ref.data()); // Enzyme Jacobian - dsquare(x, sq, dsq); + dsquare(x.size(), x.data(), sq.data(), dsq.data()); // Check int fail = 0; From 23dc868464aa12894a3324ba297c49a5175307f6 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 25 Nov 2024 11:18:41 -0500 Subject: [PATCH 11/52] Attempt to use classes in EnzymeLibCheck. --- Examples/Enzyme/Library/CMakeLists.txt | 2 +- Examples/Enzyme/Library/EnzymeWrapper.hpp | 18 ++++++++++++ Examples/Enzyme/Library/Library.cpp | 34 +++++++++++++++++++++++ Examples/Enzyme/Library/Library.hpp | 17 ++++++++++++ Examples/Enzyme/Library/library.cpp | 3 -- Examples/Enzyme/Library/library.hpp | 2 -- Examples/Enzyme/Library/main.cpp | 17 +++++++----- 7 files changed, 80 insertions(+), 13 deletions(-) create mode 100644 Examples/Enzyme/Library/EnzymeWrapper.hpp create mode 100644 Examples/Enzyme/Library/Library.cpp create mode 100644 Examples/Enzyme/Library/Library.hpp delete mode 100644 Examples/Enzyme/Library/library.cpp delete mode 100644 Examples/Enzyme/Library/library.hpp diff --git a/Examples/Enzyme/Library/CMakeLists.txt b/Examples/Enzyme/Library/CMakeLists.txt index 78566c983..b1c5d8427 100644 --- a/Examples/Enzyme/Library/CMakeLists.txt +++ b/Examples/Enzyme/Library/CMakeLists.txt @@ -1,4 +1,4 @@ -enzyme_add_executable(NAME EnzymeLibCheck SOURCES main.cpp library.cpp) +enzyme_add_executable(NAME EnzymeLibCheck SOURCES main.cpp Library.cpp) #install(TARGETS ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibCheck DESTINATION bin) add_test(NAME "EnzymeLibCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibCheck) diff --git a/Examples/Enzyme/Library/EnzymeWrapper.hpp b/Examples/Enzyme/Library/EnzymeWrapper.hpp new file mode 100644 index 000000000..b72f17c33 --- /dev/null +++ b/Examples/Enzyme/Library/EnzymeWrapper.hpp @@ -0,0 +1,18 @@ +#pragma once + +int enzyme_dup; +int enzyme_dupnoneed; +int enzyme_out; +int enzyme_const; + +template +return_type __enzyme_fwddiff(return_type*, int, T* ... ); + +template +return_type __enzyme_autodiff(return_type*, int, T* ... ); + +template +return_type wrapper(T* obj) { + obj->evalFunction(); + return obj->getFunctionValue(); +} diff --git a/Examples/Enzyme/Library/Library.cpp b/Examples/Enzyme/Library/Library.cpp new file mode 100644 index 000000000..d378b2886 --- /dev/null +++ b/Examples/Enzyme/Library/Library.cpp @@ -0,0 +1,34 @@ +#include "EnzymeWrapper.hpp" +#include "Library.hpp" +#include + +inline +double Model::square(double x) { + return x * x; +} + +void Model::setVariable(double x) { + x_ = x; +} + +void Model::evalFunction() { + f_ = square(x_); +} + +void Model::evalDerivative() { + Model dModel; + dModel.setVariable(1.0); + dfdx_ = __enzyme_fwddiff((double*)wrapper, enzyme_dup, this, &dModel); +} + +double Model::getVariable() const { + return x_; +} + +double Model::getFunctionValue() const { + return f_; +} + +double Model::getDerivativeValue() const { + return dfdx_; +} diff --git a/Examples/Enzyme/Library/Library.hpp b/Examples/Enzyme/Library/Library.hpp new file mode 100644 index 000000000..8d8461fb6 --- /dev/null +++ b/Examples/Enzyme/Library/Library.hpp @@ -0,0 +1,17 @@ +#pragma once + +class Model { +private: + double x_, f_, dfdx_; + inline double square(double); + +public: + Model() {}; + void setVariable(double); + void evalFunction(); + void evalDerivative(); + double getVariable() const; + double getFunctionValue() const; + double getDerivativeValue() const; + ~Model() {}; +}; diff --git a/Examples/Enzyme/Library/library.cpp b/Examples/Enzyme/Library/library.cpp deleted file mode 100644 index 6ff34da7a..000000000 --- a/Examples/Enzyme/Library/library.cpp +++ /dev/null @@ -1,3 +0,0 @@ -double square(double x) { - return x * x; -} diff --git a/Examples/Enzyme/Library/library.hpp b/Examples/Enzyme/Library/library.hpp deleted file mode 100644 index b498a295b..000000000 --- a/Examples/Enzyme/Library/library.hpp +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -double square(double x); diff --git a/Examples/Enzyme/Library/main.cpp b/Examples/Enzyme/Library/main.cpp index e0aef4ecd..c1bfad815 100644 --- a/Examples/Enzyme/Library/main.cpp +++ b/Examples/Enzyme/Library/main.cpp @@ -1,16 +1,19 @@ #include #include -#include "library.hpp" - -double __enzyme_autodiff(double (*)(double), ...); +#include "Library.hpp" int main() { int fail = 0; - double sq = square(5.0); - double dsq = __enzyme_autodiff(square, 5.0); + Model model; + double var = 5.0; + model.setVariable(var); + model.evalFunction(); + model.evalDerivative(); + double sq = model.getFunctionValue(); + double dsq = model.getDerivativeValue(); - std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; - if (std::abs(dsq - 10.0) > std::numeric_limits::epsilon()) + std::cout << "x = " << var << ", x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; + if (std::abs(dsq - 2.0*var) > std::numeric_limits::epsilon()) { fail++; std::cout << "Result incorrect\n"; From 0d08de14123ef6df0d2026ddf70a3d9fec46521e Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 25 Nov 2024 13:02:25 -0500 Subject: [PATCH 12/52] Minor improvements in scalar and vector Enzyme standalone tests. --- Examples/Enzyme/Standalone/scalar.cpp | 10 +++++----- Examples/Enzyme/Standalone/vector.cpp | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Examples/Enzyme/Standalone/scalar.cpp b/Examples/Enzyme/Standalone/scalar.cpp index c9b81ef05..1372fcddd 100644 --- a/Examples/Enzyme/Standalone/scalar.cpp +++ b/Examples/Enzyme/Standalone/scalar.cpp @@ -10,14 +10,14 @@ double dsquare(double x) { return __enzyme_autodiff(square, x); } -double sq = square(5.0); -double dsq = dsquare(5.0); - int main() { int fail = 0; - std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; - if (std::abs(dsq - 10.0) > std::numeric_limits::epsilon()) + double var = 5.0; + double sq = square(var); + double dsq = dsquare(var); + std::cout << "x = " << var << ", x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; + if (std::abs(dsq - 2.0*var) > std::numeric_limits::epsilon()) { fail++; std::cout << "Result incorrect\n"; diff --git a/Examples/Enzyme/Standalone/vector.cpp b/Examples/Enzyme/Standalone/vector.cpp index 5f6ed82e5..be76f9900 100644 --- a/Examples/Enzyme/Standalone/vector.cpp +++ b/Examples/Enzyme/Standalone/vector.cpp @@ -66,7 +66,7 @@ void dsquare(int N, double* x, double* y, double* dy) { int main() { // Vector declarations - constexpr int N = 2; + constexpr int N = 10; std::vector x(N); std::vector sq(N); std::vector dsq(N*N); From cc83e0f0c499fb4c7373fc1d5fdd0b5806885745 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 9 Dec 2024 15:40:01 -0500 Subject: [PATCH 13/52] Minor name change for Enzyme test files. --- Examples/Enzyme/Standalone/CMakeLists.txt | 4 ++-- Examples/Enzyme/Standalone/{scalar.cpp => EnzymeScalar.cpp} | 0 Examples/Enzyme/Standalone/{vector.cpp => EnzymeVector.cpp} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename Examples/Enzyme/Standalone/{scalar.cpp => EnzymeScalar.cpp} (100%) rename Examples/Enzyme/Standalone/{vector.cpp => EnzymeVector.cpp} (100%) diff --git a/Examples/Enzyme/Standalone/CMakeLists.txt b/Examples/Enzyme/Standalone/CMakeLists.txt index e71df5101..f78eb3c93 100644 --- a/Examples/Enzyme/Standalone/CMakeLists.txt +++ b/Examples/Enzyme/Standalone/CMakeLists.txt @@ -1,11 +1,11 @@ enzyme_add_executable( NAME EnzymeStandaloneScalarCheck - SOURCES scalar.cpp + SOURCES EnzymeScalar.cpp ) enzyme_add_executable( NAME EnzymeStandaloneVectorCheck - SOURCES vector.cpp + SOURCES EnzymeVector.cpp ) add_test(NAME "EnzymeStandaloneScalarCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneScalarCheck) diff --git a/Examples/Enzyme/Standalone/scalar.cpp b/Examples/Enzyme/Standalone/EnzymeScalar.cpp similarity index 100% rename from Examples/Enzyme/Standalone/scalar.cpp rename to Examples/Enzyme/Standalone/EnzymeScalar.cpp diff --git a/Examples/Enzyme/Standalone/vector.cpp b/Examples/Enzyme/Standalone/EnzymeVector.cpp similarity index 100% rename from Examples/Enzyme/Standalone/vector.cpp rename to Examples/Enzyme/Standalone/EnzymeVector.cpp From fa3c09a640e0cfd6a02b6b74631b80cda4b1fa33 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 3 Feb 2025 13:19:38 -0500 Subject: [PATCH 14/52] Move Enzyme examples. --- {Examples => examples/Enzyme}/Enzyme/CMakeLists.txt | 0 {Examples => examples/Enzyme}/Enzyme/Library/CMakeLists.txt | 0 {Examples => examples/Enzyme}/Enzyme/Library/EnzymeWrapper.hpp | 0 {Examples => examples/Enzyme}/Enzyme/Library/Library.cpp | 0 {Examples => examples/Enzyme}/Enzyme/Library/Library.hpp | 0 {Examples => examples/Enzyme}/Enzyme/Library/main.cpp | 0 {Examples => examples/Enzyme}/Enzyme/Standalone/CMakeLists.txt | 0 {Examples => examples/Enzyme}/Enzyme/Standalone/EnzymeScalar.cpp | 0 {Examples => examples/Enzyme}/Enzyme/Standalone/EnzymeVector.cpp | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename {Examples => examples/Enzyme}/Enzyme/CMakeLists.txt (100%) rename {Examples => examples/Enzyme}/Enzyme/Library/CMakeLists.txt (100%) rename {Examples => examples/Enzyme}/Enzyme/Library/EnzymeWrapper.hpp (100%) rename {Examples => examples/Enzyme}/Enzyme/Library/Library.cpp (100%) rename {Examples => examples/Enzyme}/Enzyme/Library/Library.hpp (100%) rename {Examples => examples/Enzyme}/Enzyme/Library/main.cpp (100%) rename {Examples => examples/Enzyme}/Enzyme/Standalone/CMakeLists.txt (100%) rename {Examples => examples/Enzyme}/Enzyme/Standalone/EnzymeScalar.cpp (100%) rename {Examples => examples/Enzyme}/Enzyme/Standalone/EnzymeVector.cpp (100%) diff --git a/Examples/Enzyme/CMakeLists.txt b/examples/Enzyme/Enzyme/CMakeLists.txt similarity index 100% rename from Examples/Enzyme/CMakeLists.txt rename to examples/Enzyme/Enzyme/CMakeLists.txt diff --git a/Examples/Enzyme/Library/CMakeLists.txt b/examples/Enzyme/Enzyme/Library/CMakeLists.txt similarity index 100% rename from Examples/Enzyme/Library/CMakeLists.txt rename to examples/Enzyme/Enzyme/Library/CMakeLists.txt diff --git a/Examples/Enzyme/Library/EnzymeWrapper.hpp b/examples/Enzyme/Enzyme/Library/EnzymeWrapper.hpp similarity index 100% rename from Examples/Enzyme/Library/EnzymeWrapper.hpp rename to examples/Enzyme/Enzyme/Library/EnzymeWrapper.hpp diff --git a/Examples/Enzyme/Library/Library.cpp b/examples/Enzyme/Enzyme/Library/Library.cpp similarity index 100% rename from Examples/Enzyme/Library/Library.cpp rename to examples/Enzyme/Enzyme/Library/Library.cpp diff --git a/Examples/Enzyme/Library/Library.hpp b/examples/Enzyme/Enzyme/Library/Library.hpp similarity index 100% rename from Examples/Enzyme/Library/Library.hpp rename to examples/Enzyme/Enzyme/Library/Library.hpp diff --git a/Examples/Enzyme/Library/main.cpp b/examples/Enzyme/Enzyme/Library/main.cpp similarity index 100% rename from Examples/Enzyme/Library/main.cpp rename to examples/Enzyme/Enzyme/Library/main.cpp diff --git a/Examples/Enzyme/Standalone/CMakeLists.txt b/examples/Enzyme/Enzyme/Standalone/CMakeLists.txt similarity index 100% rename from Examples/Enzyme/Standalone/CMakeLists.txt rename to examples/Enzyme/Enzyme/Standalone/CMakeLists.txt diff --git a/Examples/Enzyme/Standalone/EnzymeScalar.cpp b/examples/Enzyme/Enzyme/Standalone/EnzymeScalar.cpp similarity index 100% rename from Examples/Enzyme/Standalone/EnzymeScalar.cpp rename to examples/Enzyme/Enzyme/Standalone/EnzymeScalar.cpp diff --git a/Examples/Enzyme/Standalone/EnzymeVector.cpp b/examples/Enzyme/Enzyme/Standalone/EnzymeVector.cpp similarity index 100% rename from Examples/Enzyme/Standalone/EnzymeVector.cpp rename to examples/Enzyme/Enzyme/Standalone/EnzymeVector.cpp From caeef0cad710919272d239ca42c57751f8fd8a32 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 3 Feb 2025 13:20:53 -0500 Subject: [PATCH 15/52] Minor edits to match develop --- CMakeLists.txt | 3 --- cmake/FindSuiteSparse.cmake | 6 +++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a86d76e46..3fbba2cb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,9 +130,6 @@ if(GRIDKIT_ENABLE_SUNDIALS) find_package(SUNDIALS 7.0.0 REQUIRED CONFIG PATHS ${SUNDIALS_DIR} ${SUNDIALS_DIR}/lib/cmake/sundials) - if("${SUNDIALS_VERSION}" VERSION_LESS "6.0.0") - message(FATAL_ERROR "GridKit requires SUNDIALS >= 6.0.0, got ${SUNDIALS_VERSION}") - endif() message(STATUS "SUNDIALS configuration found: ${SUNDIALS_CONFIG}") endif() if(GRIDKIT_ENABLE_SUNDIALS_SPARSE) diff --git a/cmake/FindSuiteSparse.cmake b/cmake/FindSuiteSparse.cmake index 550b55e54..5a1026935 100644 --- a/cmake/FindSuiteSparse.cmake +++ b/cmake/FindSuiteSparse.cmake @@ -123,15 +123,15 @@ if(SUITESPARSE_LIBRARY) endforeach(mod) else() if(NOT SUITESPARSE_ROOT_DIR) - message(FATAL_ERROR "Suitesparse dir not found! Please provide correct filepath.") + message(STATUS "Suitesparse dir not found! Please provide correct filepath.") set(SUITESPARSE_DIR ${SUITESPARSE_DIR} CACHE PATH "Path to Suitesparse installation root.") unset(SUITESPARSE_LIBRARY CACHE) unset(SUITESPARSE_INCLUDE_DIR CACHE) unset(SUITESPARSE_LIBRARY_DIR CACHE) elseif(NOT SUITESPARSE_LIBRARY) - message(FATAL_ERROR "Suitesparse library not found! Please provide correct filepath.") + message(STATUS "Suitesparse library not found! Please provide correct filepath.") endif() if(SUITESPARSE_ROOT_DIR AND NOT SUITESPARSE_INCLUDE_DIR) - message(FATAL_ERROR "Suitesparse include dir not found! Please provide correct filepath.") + message(STATUS "Suitesparse include dir not found! Please provide correct filepath.") endif() endif() From e99987761bb4c76116ea2fee76e5e393a2b25f86 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 3 Feb 2025 15:54:29 -0500 Subject: [PATCH 16/52] LinearAlgebra directory in examples and DenseTest. --- examples/CMakeLists.txt | 2 +- examples/LinearAlgebra/CMakeLists.txt | 3 + .../LinearAlgebra/DenseTest/CMakeLists.txt | 6 + .../LinearAlgebra/DenseTest/DenseTest.cpp | 25 ++++ .../SparseTest/CMakeLists.txt | 0 .../SparseTest/SparseTest.cpp | 0 src/LinearAlgebra/CMakeLists.txt | 1 + src/LinearAlgebra/DenseMatrix/CMakeLists.txt | 6 + src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp | 122 ++++++++++++++++++ 9 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 examples/LinearAlgebra/CMakeLists.txt create mode 100644 examples/LinearAlgebra/DenseTest/CMakeLists.txt create mode 100644 examples/LinearAlgebra/DenseTest/DenseTest.cpp rename examples/{ => LinearAlgebra}/SparseTest/CMakeLists.txt (100%) rename examples/{ => LinearAlgebra}/SparseTest/SparseTest.cpp (100%) create mode 100644 src/LinearAlgebra/DenseMatrix/CMakeLists.txt create mode 100644 src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 5b75c689b..100de2338 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -56,7 +56,7 @@ # add_subdirectory(MatPowerTesting) -add_subdirectory(SparseTest) +add_subdirectory(LinearAlgebra) add_subdirectory(DistributedGeneratorTest) if(TARGET SUNDIALS::kinsol) diff --git a/examples/LinearAlgebra/CMakeLists.txt b/examples/LinearAlgebra/CMakeLists.txt new file mode 100644 index 000000000..553b0587e --- /dev/null +++ b/examples/LinearAlgebra/CMakeLists.txt @@ -0,0 +1,3 @@ + +add_subdirectory(SparseTest) +add_subdirectory(DenseTest) diff --git a/examples/LinearAlgebra/DenseTest/CMakeLists.txt b/examples/LinearAlgebra/DenseTest/CMakeLists.txt new file mode 100644 index 000000000..5d3bf7b5c --- /dev/null +++ b/examples/LinearAlgebra/DenseTest/CMakeLists.txt @@ -0,0 +1,6 @@ + +add_executable(densemattest DenseTest.cpp) +target_link_libraries(densemattest GRIDKIT::DenseMatrix) + +add_test(NAME DenseMatrixTest COMMAND $) +install(TARGETS densemattest RUNTIME DESTINATION bin) diff --git a/examples/LinearAlgebra/DenseTest/DenseTest.cpp b/examples/LinearAlgebra/DenseTest/DenseTest.cpp new file mode 100644 index 000000000..85eeb5a76 --- /dev/null +++ b/examples/LinearAlgebra/DenseTest/DenseTest.cpp @@ -0,0 +1,25 @@ + +#include + +int main() +{ + int fail = 0; + + size_t m = 4; + size_t n = 4; + GridKit::LinearAlgebra::DenseMatrix A = + GridKit::LinearAlgebra::DenseMatrix(m, n); + + double val = 0.0; + for (size_t j = 0; j < n; ++j) + { + for (size_t i = 0; i < m; ++i) + { + A.setValue(i, j, val); + val += 1.0; + } + } + A.printMatrix(); + + return fail; +} diff --git a/examples/SparseTest/CMakeLists.txt b/examples/LinearAlgebra/SparseTest/CMakeLists.txt similarity index 100% rename from examples/SparseTest/CMakeLists.txt rename to examples/LinearAlgebra/SparseTest/CMakeLists.txt diff --git a/examples/SparseTest/SparseTest.cpp b/examples/LinearAlgebra/SparseTest/SparseTest.cpp similarity index 100% rename from examples/SparseTest/SparseTest.cpp rename to examples/LinearAlgebra/SparseTest/SparseTest.cpp diff --git a/src/LinearAlgebra/CMakeLists.txt b/src/LinearAlgebra/CMakeLists.txt index eeda5e797..d290617be 100644 --- a/src/LinearAlgebra/CMakeLists.txt +++ b/src/LinearAlgebra/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(SparseMatrix) +add_subdirectory(DenseMatrix) diff --git a/src/LinearAlgebra/DenseMatrix/CMakeLists.txt b/src/LinearAlgebra/DenseMatrix/CMakeLists.txt new file mode 100644 index 000000000..37eb294c3 --- /dev/null +++ b/src/LinearAlgebra/DenseMatrix/CMakeLists.txt @@ -0,0 +1,6 @@ + +add_library(DenseMatrix INTERFACE) +include_directories(DenseMatrix INTERFACE ${CMAKE_CURRENT_LIST_DIR}) + +add_library(GRIDKIT::DenseMatrix ALIAS DenseMatrix) + diff --git a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp new file mode 100644 index 000000000..3f23f74e9 --- /dev/null +++ b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp @@ -0,0 +1,122 @@ +#pragma once + +#include +#include +#include +#include + +/** + * @brief Class to provide dense matrices. + * + * This is intended for small matrices that store model Jacobians to be subsequently copied + * into large sparse matrices. + */ +namespace GridKit +{ +namespace LinearAlgebra +{ +template +class DenseMatrix +{ +private: + Intdx rows_size_; + Intdx columns_size_; + std::vector values_; + +public: + // Constructors and destructors + DenseMatrix(const Intdx rows_size, const Intdx columns_size); + ~DenseMatrix(); + + // Getters and setters + ScalarT getValue(const Intdx i, const Intdx j) const; + void setValue(const Intdx i, const Intdx j, const ScalarT value); + + // Utilities + void printMatrix(); + + // Purposefully not defining BLAS operations. This class should not be used + // for compute. +}; + +/** + * @brief DenseMatrix constructor + * + * @tparam ScalarT + * @tparam Intdx + */ +template +DenseMatrix::DenseMatrix(const Intdx rows_size, const Intdx columns_size) : + rows_size_(rows_size), + columns_size_(columns_size), + values_(rows_size*columns_size, 0) +{ + +} + +/** + * @brief DenseMatrix single value getter + * + * @tparam ScalarT + * @tparam Intdx + */ +template +inline ScalarT DenseMatrix::getValue(const Intdx i, const Intdx j) const +{ + assert(i < this->colums_size_); + assert(j < this->rows_size_); + return this->values_[j*rows_size_+i]; +} + +/** + * @brief DenseMatrix single value setter + * + * @tparam ScalarT + * @tparam Intdx + */ +template +inline void DenseMatrix::setValue(const Intdx i, const Intdx j, const ScalarT value) +{ + assert(i < this->colums_size_); + assert(j < this->rows_size_); + this->values_[j*rows_size_+i] = value; +} + +/** + * @brief Print matrix + * + * @tparam ScalarT + * @tparam Intdx + */ +template +inline void DenseMatrix::printMatrix() +{ + std::cout << "Dense matrix\n"; + for (size_t i = 0; i < this->rows_size_; ++i) + { + for (size_t j = 0; j < this->columns_size_; ++j) + { + std::cout << this->values_[j*rows_size_+i] << " "; + } + std::cout << "\n"; + } +} + +/** + * @brief DenseMatrix destructor + * + * @tparam ScalarT + * @tparam Intdx + */ +template +DenseMatrix::~DenseMatrix() +{ + +} + +// Available template instantiations +template class DenseMatrix; + +} // LinearAlgebra +} // GridKit + From c0694dd94536dfb30423e56dca90c19b98f74fe8 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Thu, 6 Feb 2025 16:55:45 -0500 Subject: [PATCH 17/52] Fix path of example using Enzyme for vectors and Jacobians. --- examples/Enzyme/Enzyme/CMakeLists.txt | 2 -- examples/Enzyme/Enzyme/Library/CMakeLists.txt | 4 --- examples/Enzyme/Enzyme/Library/main.cpp | 23 ---------------- .../Enzyme/Enzyme/Standalone/CMakeLists.txt | 12 --------- examples/Enzyme/Library/CMakeLists.txt | 2 +- .../{Enzyme => }/Library/EnzymeWrapper.hpp | 0 .../Enzyme/{Enzyme => }/Library/Library.cpp | 0 .../Enzyme/{Enzyme => }/Library/Library.hpp | 0 examples/Enzyme/Library/library.cpp | 3 --- examples/Enzyme/Library/library.hpp | 2 -- examples/Enzyme/Library/main.cpp | 17 +++++++----- examples/Enzyme/Standalone/CMakeLists.txt | 12 ++++++--- .../{Enzyme => }/Standalone/EnzymeScalar.cpp | 0 .../{Enzyme => }/Standalone/EnzymeVector.cpp | 0 examples/Enzyme/Standalone/main.cpp | 27 ------------------- 15 files changed, 20 insertions(+), 84 deletions(-) delete mode 100644 examples/Enzyme/Enzyme/CMakeLists.txt delete mode 100644 examples/Enzyme/Enzyme/Library/CMakeLists.txt delete mode 100644 examples/Enzyme/Enzyme/Library/main.cpp delete mode 100644 examples/Enzyme/Enzyme/Standalone/CMakeLists.txt rename examples/Enzyme/{Enzyme => }/Library/EnzymeWrapper.hpp (100%) rename examples/Enzyme/{Enzyme => }/Library/Library.cpp (100%) rename examples/Enzyme/{Enzyme => }/Library/Library.hpp (100%) delete mode 100644 examples/Enzyme/Library/library.cpp delete mode 100644 examples/Enzyme/Library/library.hpp rename examples/Enzyme/{Enzyme => }/Standalone/EnzymeScalar.cpp (100%) rename examples/Enzyme/{Enzyme => }/Standalone/EnzymeVector.cpp (100%) delete mode 100644 examples/Enzyme/Standalone/main.cpp diff --git a/examples/Enzyme/Enzyme/CMakeLists.txt b/examples/Enzyme/Enzyme/CMakeLists.txt deleted file mode 100644 index 794ec850c..000000000 --- a/examples/Enzyme/Enzyme/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_subdirectory(Standalone) -add_subdirectory(Library) diff --git a/examples/Enzyme/Enzyme/Library/CMakeLists.txt b/examples/Enzyme/Enzyme/Library/CMakeLists.txt deleted file mode 100644 index b1c5d8427..000000000 --- a/examples/Enzyme/Enzyme/Library/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -enzyme_add_executable(NAME EnzymeLibCheck SOURCES main.cpp Library.cpp) -#install(TARGETS ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibCheck DESTINATION bin) - -add_test(NAME "EnzymeLibCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibCheck) diff --git a/examples/Enzyme/Enzyme/Library/main.cpp b/examples/Enzyme/Enzyme/Library/main.cpp deleted file mode 100644 index c1bfad815..000000000 --- a/examples/Enzyme/Enzyme/Library/main.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include "Library.hpp" - -int main() { - int fail = 0; - Model model; - double var = 5.0; - model.setVariable(var); - model.evalFunction(); - model.evalDerivative(); - double sq = model.getFunctionValue(); - double dsq = model.getDerivativeValue(); - - std::cout << "x = " << var << ", x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; - if (std::abs(dsq - 2.0*var) > std::numeric_limits::epsilon()) - { - fail++; - std::cout << "Result incorrect\n"; - } - std::cout << "Status: " << fail << "\n"; - return fail; -} diff --git a/examples/Enzyme/Enzyme/Standalone/CMakeLists.txt b/examples/Enzyme/Enzyme/Standalone/CMakeLists.txt deleted file mode 100644 index f78eb3c93..000000000 --- a/examples/Enzyme/Enzyme/Standalone/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -enzyme_add_executable( - NAME EnzymeStandaloneScalarCheck - SOURCES EnzymeScalar.cpp - ) - -enzyme_add_executable( - NAME EnzymeStandaloneVectorCheck - SOURCES EnzymeVector.cpp - ) - -add_test(NAME "EnzymeStandaloneScalarCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneScalarCheck) -add_test(NAME "EnzymeStandaloneVectorCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneVectorCheck) diff --git a/examples/Enzyme/Library/CMakeLists.txt b/examples/Enzyme/Library/CMakeLists.txt index 78566c983..b1c5d8427 100644 --- a/examples/Enzyme/Library/CMakeLists.txt +++ b/examples/Enzyme/Library/CMakeLists.txt @@ -1,4 +1,4 @@ -enzyme_add_executable(NAME EnzymeLibCheck SOURCES main.cpp library.cpp) +enzyme_add_executable(NAME EnzymeLibCheck SOURCES main.cpp Library.cpp) #install(TARGETS ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibCheck DESTINATION bin) add_test(NAME "EnzymeLibCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibCheck) diff --git a/examples/Enzyme/Enzyme/Library/EnzymeWrapper.hpp b/examples/Enzyme/Library/EnzymeWrapper.hpp similarity index 100% rename from examples/Enzyme/Enzyme/Library/EnzymeWrapper.hpp rename to examples/Enzyme/Library/EnzymeWrapper.hpp diff --git a/examples/Enzyme/Enzyme/Library/Library.cpp b/examples/Enzyme/Library/Library.cpp similarity index 100% rename from examples/Enzyme/Enzyme/Library/Library.cpp rename to examples/Enzyme/Library/Library.cpp diff --git a/examples/Enzyme/Enzyme/Library/Library.hpp b/examples/Enzyme/Library/Library.hpp similarity index 100% rename from examples/Enzyme/Enzyme/Library/Library.hpp rename to examples/Enzyme/Library/Library.hpp diff --git a/examples/Enzyme/Library/library.cpp b/examples/Enzyme/Library/library.cpp deleted file mode 100644 index 6ff34da7a..000000000 --- a/examples/Enzyme/Library/library.cpp +++ /dev/null @@ -1,3 +0,0 @@ -double square(double x) { - return x * x; -} diff --git a/examples/Enzyme/Library/library.hpp b/examples/Enzyme/Library/library.hpp deleted file mode 100644 index b498a295b..000000000 --- a/examples/Enzyme/Library/library.hpp +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -double square(double x); diff --git a/examples/Enzyme/Library/main.cpp b/examples/Enzyme/Library/main.cpp index e0aef4ecd..c1bfad815 100644 --- a/examples/Enzyme/Library/main.cpp +++ b/examples/Enzyme/Library/main.cpp @@ -1,16 +1,19 @@ #include #include -#include "library.hpp" - -double __enzyme_autodiff(double (*)(double), ...); +#include "Library.hpp" int main() { int fail = 0; - double sq = square(5.0); - double dsq = __enzyme_autodiff(square, 5.0); + Model model; + double var = 5.0; + model.setVariable(var); + model.evalFunction(); + model.evalDerivative(); + double sq = model.getFunctionValue(); + double dsq = model.getDerivativeValue(); - std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; - if (std::abs(dsq - 10.0) > std::numeric_limits::epsilon()) + std::cout << "x = " << var << ", x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; + if (std::abs(dsq - 2.0*var) > std::numeric_limits::epsilon()) { fail++; std::cout << "Result incorrect\n"; diff --git a/examples/Enzyme/Standalone/CMakeLists.txt b/examples/Enzyme/Standalone/CMakeLists.txt index 919d755e0..f78eb3c93 100644 --- a/examples/Enzyme/Standalone/CMakeLists.txt +++ b/examples/Enzyme/Standalone/CMakeLists.txt @@ -1,6 +1,12 @@ enzyme_add_executable( - NAME EnzymeStandaloneCheck - SOURCES main.cpp + NAME EnzymeStandaloneScalarCheck + SOURCES EnzymeScalar.cpp ) -add_test(NAME "EnzymeStandaloneCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneCheck) +enzyme_add_executable( + NAME EnzymeStandaloneVectorCheck + SOURCES EnzymeVector.cpp + ) + +add_test(NAME "EnzymeStandaloneScalarCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneScalarCheck) +add_test(NAME "EnzymeStandaloneVectorCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneVectorCheck) diff --git a/examples/Enzyme/Enzyme/Standalone/EnzymeScalar.cpp b/examples/Enzyme/Standalone/EnzymeScalar.cpp similarity index 100% rename from examples/Enzyme/Enzyme/Standalone/EnzymeScalar.cpp rename to examples/Enzyme/Standalone/EnzymeScalar.cpp diff --git a/examples/Enzyme/Enzyme/Standalone/EnzymeVector.cpp b/examples/Enzyme/Standalone/EnzymeVector.cpp similarity index 100% rename from examples/Enzyme/Enzyme/Standalone/EnzymeVector.cpp rename to examples/Enzyme/Standalone/EnzymeVector.cpp diff --git a/examples/Enzyme/Standalone/main.cpp b/examples/Enzyme/Standalone/main.cpp deleted file mode 100644 index c9b81ef05..000000000 --- a/examples/Enzyme/Standalone/main.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include - -double square(double x) { - return x * x; -} - -double __enzyme_autodiff(double(*)(double), ...); -double dsquare(double x) { - return __enzyme_autodiff(square, x); -} - -double sq = square(5.0); -double dsq = dsquare(5.0); - -int main() -{ - int fail = 0; - std::cout << "x = 5, x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; - if (std::abs(dsq - 10.0) > std::numeric_limits::epsilon()) - { - fail++; - std::cout << "Result incorrect\n"; - } - std::cout << "Status: " << fail << "\n"; - return fail; -} From 1a6260d823fe2e401b6743e39809a55cd227b089 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Thu, 6 Feb 2025 17:15:03 -0500 Subject: [PATCH 18/52] Cleanup Enzyme CMakeList. --- examples/Enzyme/Library/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/Enzyme/Library/CMakeLists.txt b/examples/Enzyme/Library/CMakeLists.txt index b1c5d8427..72e346876 100644 --- a/examples/Enzyme/Library/CMakeLists.txt +++ b/examples/Enzyme/Library/CMakeLists.txt @@ -1,4 +1,3 @@ enzyme_add_executable(NAME EnzymeLibCheck SOURCES main.cpp Library.cpp) -#install(TARGETS ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibCheck DESTINATION bin) add_test(NAME "EnzymeLibCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibCheck) From e84ad62b02b51e94e35bb602551247142ff5e323 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Fri, 7 Feb 2025 16:43:47 -0500 Subject: [PATCH 19/52] Bug fix (type): columns in DenseMatrix. --- src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp index 3f23f74e9..4f3ed66e3 100644 --- a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp +++ b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp @@ -63,7 +63,7 @@ DenseMatrix::DenseMatrix(const Intdx rows_size, const Intdx colu template inline ScalarT DenseMatrix::getValue(const Intdx i, const Intdx j) const { - assert(i < this->colums_size_); + assert(i < this->columns_size_); assert(j < this->rows_size_); return this->values_[j*rows_size_+i]; } @@ -77,7 +77,7 @@ inline ScalarT DenseMatrix::getValue(const Intdx i, const Intdx template inline void DenseMatrix::setValue(const Intdx i, const Intdx j, const ScalarT value) { - assert(i < this->colums_size_); + assert(i < this->columns_size_); assert(j < this->rows_size_); this->values_[j*rows_size_+i] = value; } From 9294ed3854610292a8a3def6a0eb809abb4ec88a Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Fri, 7 Feb 2025 17:25:20 -0500 Subject: [PATCH 20/52] A very manual way to link GridKit targets with Enzyme executables. Need to find a better way. --- cmake/FindEnzyme.cmake | 17 ++++++++++++++--- examples/Enzyme/Standalone/CMakeLists.txt | 1 + examples/Enzyme/Standalone/EnzymeVector.cpp | 1 + 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/cmake/FindEnzyme.cmake b/cmake/FindEnzyme.cmake index 21cec75f1..bb3dfa345 100644 --- a/cmake/FindEnzyme.cmake +++ b/cmake/FindEnzyme.cmake @@ -135,7 +135,7 @@ endif() macro(enzyme_add_executable) set(options) set(oneValueArgs NAME) - set(multiValueArgs SOURCES LINK_LIBRARIES) + set(multiValueArgs SOURCES LINK_LIBRARIES INCLUDE_DIRECTORIES) cmake_parse_arguments(enzyme_add_executable "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) @@ -145,14 +145,25 @@ macro(enzyme_add_executable) set(PHASE5 "${CMAKE_CURRENT_BINARY_DIR}/${enzyme_add_executable_NAME}") set(OBJS "") + set(includes "${enzyme_add_executable_INCLUDE_DIRECTORIES}") + + foreach(lib ${enzyme_add_executable_LINK_LIBRARIES}) + get_target_property(include ${lib} INCLUDE_DIRECTORIES) + set(includes "${includes}" ${include}) + endforeach() + + foreach(dir ${includes}) + list(APPEND INCLUDE_COMPILER_LIST "-I${dir}") + break() + endforeach() foreach(SRC ${enzyme_add_executable_SOURCES}) set(PHASE0 "${CMAKE_CURRENT_SOURCE_DIR}/${SRC}") set(PHASE1 "${CMAKE_CURRENT_BINARY_DIR}/${enzyme_add_executable_NAME}_${SRC}_compile.o") add_custom_command( - DEPENDS ${PHASE0} + DEPENDS ${PHASE0} OUTPUT ${PHASE1} - COMMAND ${CMAKE_CXX_COMPILER} -flto -c ${PHASE0} -O2 -fno-vectorize -ffast-math -fno-unroll-loops -o ${PHASE1} + COMMAND ${CMAKE_CXX_COMPILER} -flto -c ${PHASE0} ${INCLUDE_COMPILER_LIST} -O2 -fno-vectorize -ffast-math -fno-unroll-loops -o ${PHASE1} COMMENT "Compiling ${SRC} to object file for target ${enzyme_add_executable_NAME}" ) set(OBJS "${OBJS} ${PHASE1}") diff --git a/examples/Enzyme/Standalone/CMakeLists.txt b/examples/Enzyme/Standalone/CMakeLists.txt index f78eb3c93..64350af6f 100644 --- a/examples/Enzyme/Standalone/CMakeLists.txt +++ b/examples/Enzyme/Standalone/CMakeLists.txt @@ -6,6 +6,7 @@ enzyme_add_executable( enzyme_add_executable( NAME EnzymeStandaloneVectorCheck SOURCES EnzymeVector.cpp + LINK_LIBRARIES GRIDKIT::DenseMatrix ) add_test(NAME "EnzymeStandaloneScalarCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneScalarCheck) diff --git a/examples/Enzyme/Standalone/EnzymeVector.cpp b/examples/Enzyme/Standalone/EnzymeVector.cpp index be76f9900..9419c3ae0 100644 --- a/examples/Enzyme/Standalone/EnzymeVector.cpp +++ b/examples/Enzyme/Standalone/EnzymeVector.cpp @@ -1,6 +1,7 @@ #include #include #include +#include int enzyme_dupnoneed; int enzyme_dup; From 2d9200bc6647a4038af541923cd0fe54164b46de Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Fri, 7 Feb 2025 17:34:03 -0500 Subject: [PATCH 21/52] Fixed spacing in Enzyme examples --- examples/Enzyme/Library/EnzymeWrapper.hpp | 4 +- examples/Enzyme/Library/Library.cpp | 18 +-- examples/Enzyme/Library/Library.hpp | 20 +-- examples/Enzyme/Library/main.cpp | 34 ++--- examples/Enzyme/Standalone/EnzymeScalar.cpp | 24 ++-- examples/Enzyme/Standalone/EnzymeVector.cpp | 148 ++++++++++---------- 6 files changed, 124 insertions(+), 124 deletions(-) diff --git a/examples/Enzyme/Library/EnzymeWrapper.hpp b/examples/Enzyme/Library/EnzymeWrapper.hpp index b72f17c33..4830521bb 100644 --- a/examples/Enzyme/Library/EnzymeWrapper.hpp +++ b/examples/Enzyme/Library/EnzymeWrapper.hpp @@ -13,6 +13,6 @@ return_type __enzyme_autodiff(return_type*, int, T* ... ); template return_type wrapper(T* obj) { - obj->evalFunction(); - return obj->getFunctionValue(); + obj->evalFunction(); + return obj->getFunctionValue(); } diff --git a/examples/Enzyme/Library/Library.cpp b/examples/Enzyme/Library/Library.cpp index d378b2886..eb9c7116e 100644 --- a/examples/Enzyme/Library/Library.cpp +++ b/examples/Enzyme/Library/Library.cpp @@ -4,31 +4,31 @@ inline double Model::square(double x) { - return x * x; + return x * x; } void Model::setVariable(double x) { - x_ = x; + x_ = x; } void Model::evalFunction() { - f_ = square(x_); + f_ = square(x_); } void Model::evalDerivative() { - Model dModel; - dModel.setVariable(1.0); - dfdx_ = __enzyme_fwddiff((double*)wrapper, enzyme_dup, this, &dModel); + Model dModel; + dModel.setVariable(1.0); + dfdx_ = __enzyme_fwddiff((double*)wrapper, enzyme_dup, this, &dModel); } double Model::getVariable() const { - return x_; + return x_; } double Model::getFunctionValue() const { - return f_; + return f_; } double Model::getDerivativeValue() const { - return dfdx_; + return dfdx_; } diff --git a/examples/Enzyme/Library/Library.hpp b/examples/Enzyme/Library/Library.hpp index 8d8461fb6..c74369dce 100644 --- a/examples/Enzyme/Library/Library.hpp +++ b/examples/Enzyme/Library/Library.hpp @@ -2,16 +2,16 @@ class Model { private: - double x_, f_, dfdx_; - inline double square(double); + double x_, f_, dfdx_; + inline double square(double); public: - Model() {}; - void setVariable(double); - void evalFunction(); - void evalDerivative(); - double getVariable() const; - double getFunctionValue() const; - double getDerivativeValue() const; - ~Model() {}; + Model() {}; + void setVariable(double); + void evalFunction(); + void evalDerivative(); + double getVariable() const; + double getFunctionValue() const; + double getDerivativeValue() const; + ~Model() {}; }; diff --git a/examples/Enzyme/Library/main.cpp b/examples/Enzyme/Library/main.cpp index c1bfad815..b63b1dea2 100644 --- a/examples/Enzyme/Library/main.cpp +++ b/examples/Enzyme/Library/main.cpp @@ -3,21 +3,21 @@ #include "Library.hpp" int main() { - int fail = 0; - Model model; - double var = 5.0; - model.setVariable(var); - model.evalFunction(); - model.evalDerivative(); - double sq = model.getFunctionValue(); - double dsq = model.getDerivativeValue(); - - std::cout << "x = " << var << ", x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; - if (std::abs(dsq - 2.0*var) > std::numeric_limits::epsilon()) - { - fail++; - std::cout << "Result incorrect\n"; - } - std::cout << "Status: " << fail << "\n"; - return fail; + int fail = 0; + Model model; + double var = 5.0; + model.setVariable(var); + model.evalFunction(); + model.evalDerivative(); + double sq = model.getFunctionValue(); + double dsq = model.getDerivativeValue(); + + std::cout << "x = " << var << ", x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; + if (std::abs(dsq - 2.0*var) > std::numeric_limits::epsilon()) + { + fail++; + std::cout << "Result incorrect\n"; + } + std::cout << "Status: " << fail << "\n"; + return fail; } diff --git a/examples/Enzyme/Standalone/EnzymeScalar.cpp b/examples/Enzyme/Standalone/EnzymeScalar.cpp index c6496cd78..2c4da8c7a 100644 --- a/examples/Enzyme/Standalone/EnzymeScalar.cpp +++ b/examples/Enzyme/Standalone/EnzymeScalar.cpp @@ -12,16 +12,16 @@ double dsquare(double x) { int main() { - int fail = 0; - double var = 5.0; - double sq = square(var); - double dsq = dsquare(var); - std::cout << "x = " << var << ", x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; - if (std::abs(dsq - 2.0*var) > std::numeric_limits::epsilon()) - { - fail++; - std::cout << "Result incorrect\n"; - } - std::cout << "Status: " << fail << "\n"; - return fail; + int fail = 0; + double var = 5.0; + double sq = square(var); + double dsq = dsquare(var); + std::cout << "x = " << var << ", x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; + if (std::abs(dsq - 2.0*var) > std::numeric_limits::epsilon()) + { + fail++; + std::cout << "Result incorrect\n"; + } + std::cout << "Status: " << fail << "\n"; + return fail; } diff --git a/examples/Enzyme/Standalone/EnzymeVector.cpp b/examples/Enzyme/Standalone/EnzymeVector.cpp index 9419c3ae0..90bd67889 100644 --- a/examples/Enzyme/Standalone/EnzymeVector.cpp +++ b/examples/Enzyme/Standalone/EnzymeVector.cpp @@ -10,104 +10,104 @@ void __enzyme_fwddiff(void*, ...); inline double square_scalar(double x) { - return x * x; + return x * x; } inline double dsquare_ref_scalar(double x) { - return 2.0 * x; + return 2.0 * x; } void square(int N, double* x, double* y) { - for (int idx = 0; idx < N; ++idx) - { - y[idx] = square_scalar(x[idx]); - } -} - -void dsquare_ref(int N, double* x, double* y, double* dy) { - for (int idy = 0; idy < N; ++idy) - { for (int idx = 0; idx < N; ++idx) { - dy[idy*N+idx] = 0.0; - if (idx == idy) - dy[idy*N+idx] = dsquare_ref_scalar(x[idx]); + y[idx] = square_scalar(x[idx]); } - } } -void dsquare(int N, double* x, double* y, double* dy) { - double* v = new double[N]; - double* d_y = new double[N]; - for (int idy = 0; idy < N; ++idy) - { - // Elementary vector for Jacobian-vector product - for (int idx = 0; idx < N; ++idx) +void dsquare_ref(int N, double* x, double* y, double* dy) { + for (int idy = 0; idy < N; ++idy) { - v[idx] = 0.0; + for (int idx = 0; idx < N; ++idx) + { + dy[idy*N+idx] = 0.0; + if (idx == idy) + dy[idy*N+idx] = dsquare_ref_scalar(x[idx]); + } } - v[idy] = 1.0; - - // Autodiff - __enzyme_fwddiff((void*)square, enzyme_const, N, - enzyme_dup, x, v, - enzyme_dupnoneed, y, d_y); +} - // Store result - for (int idx = 0; idx < N; ++idx) +void dsquare(int N, double* x, double* y, double* dy) { + double* v = new double[N]; + double* d_y = new double[N]; + for (int idy = 0; idy < N; ++idy) { - dy[idy*N+idx] = d_y[idx]; + // Elementary vector for Jacobian-vector product + for (int idx = 0; idx < N; ++idx) + { + v[idx] = 0.0; + } + v[idy] = 1.0; + + // Autodiff + __enzyme_fwddiff((void*)square, enzyme_const, N, + enzyme_dup, x, v, + enzyme_dupnoneed, y, d_y); + + // Store result + for (int idx = 0; idx < N; ++idx) + { + dy[idy*N+idx] = d_y[idx]; + } } - } - delete[] v; - delete[] d_y; + delete[] v; + delete[] d_y; } int main() { - // Vector declarations - constexpr int N = 10; - std::vector x(N); - std::vector sq(N); - std::vector dsq(N*N); - std::vector dsq_ref(N*N); - - // Random input values - srand(time(NULL)); - for (int idx = 0; idx < x.size(); ++idx) - { - x[idx] = rand(); - } - - // Function evaluation - square(x.size(), x.data(), sq.data()); - - // Reference Jacobian - dsquare_ref(x.size(), x.data(), sq.data(), dsq_ref.data()); - - // Enzyme Jacobian - dsquare(x.size(), x.data(), sq.data(), dsq.data()); - - // Check - int fail = 0; - bool verbose = false; - for (int idy = 0; idy < sq.size(); ++idy) - { + // Vector declarations + constexpr int N = 10; + std::vector x(N); + std::vector sq(N); + std::vector dsq(N*N); + std::vector dsq_ref(N*N); + + // Random input values + srand(time(NULL)); for (int idx = 0; idx < x.size(); ++idx) { - int idxy = idy*x.size()+idx; - if (std::abs(dsq[idxy] - dsq_ref[idxy]) > std::numeric_limits::epsilon()) - { - fail++; - if (verbose) + x[idx] = rand(); + } + + // Function evaluation + square(x.size(), x.data(), sq.data()); + + // Reference Jacobian + dsquare_ref(x.size(), x.data(), sq.data(), dsq_ref.data()); + + // Enzyme Jacobian + dsquare(x.size(), x.data(), sq.data(), dsq.data()); + + // Check + int fail = 0; + bool verbose = false; + for (int idy = 0; idy < sq.size(); ++idy) + { + for (int idx = 0; idx < x.size(); ++idx) { - std::cout << "Result incorrect at line = " << idy << ", column = " << idx << "\n"; - std::cout << "x = " << x[idx] << ", x^2 = " << sq[idx] << ", d(x^2)/dx = " << dsq[idxy] << "\n"; + int idxy = idy*x.size()+idx; + if (std::abs(dsq[idxy] - dsq_ref[idxy]) > std::numeric_limits::epsilon()) + { + fail++; + if (verbose) + { + std::cout << "Result incorrect at line = " << idy << ", column = " << idx << "\n"; + std::cout << "x = " << x[idx] << ", x^2 = " << sq[idx] << ", d(x^2)/dx = " << dsq[idxy] << "\n"; + } + } } - } } - } - std::cout << "Status: " << fail << "\n"; - return fail; + std::cout << "Status: " << fail << "\n"; + return fail; } From 88845a6ec8424e7f1249ac9f918d1915f329385c Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Fri, 7 Feb 2025 18:22:52 -0500 Subject: [PATCH 22/52] Basic usage of DenseMatrix in EnzymeVector example. --- examples/Enzyme/Standalone/EnzymeVector.cpp | 23 +++++++++++-------- .../LinearAlgebra/DenseTest/DenseTest.cpp | 1 + src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp | 19 ++++++++++++--- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/examples/Enzyme/Standalone/EnzymeVector.cpp b/examples/Enzyme/Standalone/EnzymeVector.cpp index 90bd67889..51dca61a5 100644 --- a/examples/Enzyme/Standalone/EnzymeVector.cpp +++ b/examples/Enzyme/Standalone/EnzymeVector.cpp @@ -3,6 +3,7 @@ #include #include +using DenseMatrix = GridKit::LinearAlgebra::DenseMatrix; int enzyme_dupnoneed; int enzyme_dup; int enzyme_const; @@ -66,12 +67,12 @@ void dsquare(int N, double* x, double* y, double* dy) { int main() { - // Vector declarations + // Vector and matrix declarations constexpr int N = 10; std::vector x(N); std::vector sq(N); - std::vector dsq(N*N); - std::vector dsq_ref(N*N); + DenseMatrix dsq = DenseMatrix(N, N); + DenseMatrix dsq_ref = DenseMatrix(N, N); // Random input values srand(time(NULL)); @@ -84,30 +85,34 @@ int main() square(x.size(), x.data(), sq.data()); // Reference Jacobian - dsquare_ref(x.size(), x.data(), sq.data(), dsq_ref.data()); + dsquare_ref(x.size(), x.data(), sq.data(), (dsq_ref.getValues())->data()); // Enzyme Jacobian - dsquare(x.size(), x.data(), sq.data(), dsq.data()); + dsquare(x.size(), x.data(), sq.data(), (dsq.getValues())->data()); // Check int fail = 0; - bool verbose = false; + bool verbose = true; for (int idy = 0; idy < sq.size(); ++idy) { for (int idx = 0; idx < x.size(); ++idx) { - int idxy = idy*x.size()+idx; - if (std::abs(dsq[idxy] - dsq_ref[idxy]) > std::numeric_limits::epsilon()) + if (std::abs(dsq.getValue(idx, idy) - dsq_ref.getValue(idx, idy)) > std::numeric_limits::epsilon()) { fail++; if (verbose) { std::cout << "Result incorrect at line = " << idy << ", column = " << idx << "\n"; - std::cout << "x = " << x[idx] << ", x^2 = " << sq[idx] << ", d(x^2)/dx = " << dsq[idxy] << "\n"; + std::cout << "x = " << x[idx] << ", x^2 = " << sq[idx] << ", d(x^2)/dx = " << dsq.getValue(idx, idy) << "\n"; } } } } + if (verbose) + { + dsq.printMatrix("Autodiff Jacobian"); + dsq_ref.printMatrix("Reference Jacobian"); + } std::cout << "Status: " << fail << "\n"; return fail; } diff --git a/examples/LinearAlgebra/DenseTest/DenseTest.cpp b/examples/LinearAlgebra/DenseTest/DenseTest.cpp index 85eeb5a76..3a3878d75 100644 --- a/examples/LinearAlgebra/DenseTest/DenseTest.cpp +++ b/examples/LinearAlgebra/DenseTest/DenseTest.cpp @@ -19,6 +19,7 @@ int main() val += 1.0; } } + std::cout << "Dense matrix test output\n"; A.printMatrix(); return fail; diff --git a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp index 4f3ed66e3..97f33b55c 100644 --- a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp +++ b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp @@ -31,9 +31,10 @@ class DenseMatrix // Getters and setters ScalarT getValue(const Intdx i, const Intdx j) const; void setValue(const Intdx i, const Intdx j, const ScalarT value); + std::vector* getValues(); // Utilities - void printMatrix(); + void printMatrix(std::string name=""); // Purposefully not defining BLAS operations. This class should not be used // for compute. @@ -82,6 +83,18 @@ inline void DenseMatrix::setValue(const Intdx i, const Intdx j, this->values_[j*rows_size_+i] = value; } +/** + * @brief DenseMatrix single value setter + * + * @tparam ScalarT + * @tparam Intdx + */ +template +inline std::vector* DenseMatrix::getValues() +{ + return &(this->values_); +} + /** * @brief Print matrix * @@ -89,9 +102,9 @@ inline void DenseMatrix::setValue(const Intdx i, const Intdx j, * @tparam Intdx */ template -inline void DenseMatrix::printMatrix() +inline void DenseMatrix::printMatrix(std::string name) { - std::cout << "Dense matrix\n"; + std::cout << "Dense matrix: " << name << "\n"; for (size_t i = 0; i < this->rows_size_; ++i) { for (size_t j = 0; j < this->columns_size_; ++j) From 2ff261e7b42566d5ca0210b409bda7998f2175d6 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Fri, 7 Feb 2025 19:02:54 -0500 Subject: [PATCH 23/52] Intdx-->IdxT --- src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp | 294 +++++++++--------- 1 file changed, 147 insertions(+), 147 deletions(-) diff --git a/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp b/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp index 9036085a5..6d838cb76 100644 --- a/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp +++ b/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp @@ -16,20 +16,20 @@ * * m x n sparse matrix */ -template +template class COO_Matrix { private: std::vector values_; - std::vector row_indexes_; - std::vector column_indexes_; - Intdx rows_size_; - Intdx columns_size_; + std::vector row_indexes_; + std::vector column_indexes_; + IdxT rows_size_; + IdxT columns_size_; bool sorted_; public: //Constructors - COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n); - COO_Matrix(Intdx m, Intdx n); + COO_Matrix(std::vector r, std::vector c, std::vector v, IdxT m, IdxT n); + COO_Matrix(IdxT m, IdxT n); COO_Matrix(); ~COO_Matrix(); @@ -37,46 +37,46 @@ class COO_Matrix //Operations // --- Functions which call sort --- - std::tuple, std::vector> getRowCopy(Intdx r); - std::tuple&, std::vector&, std::vector&> getEntries(); - std::tuple, std::vector, std::vector> getEntrieCopies(); - std::tuple, std::vector, std::vector> getEntrieCopiesSubMatrix(std::vector submap); + std::tuple, std::vector> getRowCopy(IdxT r); + std::tuple&, std::vector&, std::vector&> getEntries(); + std::tuple, std::vector, std::vector> getEntrieCopies(); + std::tuple, std::vector, std::vector> getEntrieCopiesSubMatrix(std::vector submap); - std::tuple, std::vector, std::vector> getDataToCSR(); - std::vector getCSRRowData(); + std::tuple, std::vector, std::vector> getDataToCSR(); + std::vector getCSRRowData(); // BLAS. Will sort before running - void setValues(std::vector r, std::vector c, std::vector v); - void axpy(ScalarT alpha, COO_Matrix& a); - void axpy(ScalarT alpha, std::vector r, std::vector c, std::vector v); + void setValues(std::vector r, std::vector c, std::vector v); + void axpy(ScalarT alpha, COO_Matrix& a); + void axpy(ScalarT alpha, std::vector r, std::vector c, std::vector v); void scal(ScalarT alpha); ScalarT frobnorm(); // --- Permutation Operations --- //No sorting is actually done. Only done when nesscary - void permutation(std::vector row_perm, std::vector col_perm); - void permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n); + void permutation(std::vector row_perm, std::vector col_perm); + void permutationSizeMap(std::vector row_perm, std::vector col_perm, IdxT m, IdxT n); void zeroMatrix(); - void identityMatrix(Intdx n); + void identityMatrix(IdxT n); //Resort values_ void sortSparse(); bool isSorted(); - Intdx nnz(); + IdxT nnz(); - std::tuple getDimensions(); + std::tuple getDimensions(); void printMatrix(); - static void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &vals); + static void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &vals); private: - Intdx indexStartRow(const std::vector &rows, Intdx r); - Intdx sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci); - bool checkIncreaseSize(Intdx r, Intdx c); + IdxT indexStartRow(const std::vector &rows, IdxT r); + IdxT sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, IdxT ri, IdxT ci); + bool checkIncreaseSize(IdxT r, IdxT c); }; @@ -84,26 +84,26 @@ class COO_Matrix * @brief Get copy of row values_ * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT * @param r - * @return std::tuple, std::vector> + * @return std::tuple, std::vector> */ -template -inline std::tuple, std::vector> COO_Matrix::getRowCopy(Intdx r) +template +inline std::tuple, std::vector> COO_Matrix::getRowCopy(IdxT r) { if (!this->sorted_) { this->sortSparse(); } - Intdx rowindex = this->indexStartRow(r); + IdxT rowindex = this->indexStartRow(r); if (rowindex == -1) { - return {std::vector(),std::vector()}; + return {std::vector(),std::vector()}; } - Intdx rsize = rowindex; + IdxT rsize = rowindex; do { rsize++; @@ -116,11 +116,11 @@ inline std::tuple, std::vector> COO_Matrix, std::vector, std::vector> + * @tparam IdxT + * @return std::tuple, std::vector, std::vector> */ -template -inline std::tuple&, std::vector&, std::vector&> COO_Matrix::getEntries() +template +inline std::tuple&, std::vector&, std::vector&> COO_Matrix::getEntries() { if (!this->sorted_) { @@ -133,11 +133,11 @@ inline std::tuple&, std::vector&, std::vector * @brief Get copies of the data. Sorted_ before returning * * @tparam ScalarT - * @tparam Intdx - * @return std::tuple, std::vector, std::vector> + * @tparam IdxT + * @return std::tuple, std::vector, std::vector> */ -template -inline std::tuple, std::vector, std::vector> COO_Matrix::getEntrieCopies() +template +inline std::tuple, std::vector, std::vector> COO_Matrix::getEntrieCopies() { if (!this->sorted_) { @@ -150,19 +150,19 @@ inline std::tuple, std::vector, std::vector> * @brief Returns the data into CSR Format * * @tparam ScalarT - * @tparam Intdx - * @return std::tuple, std::vector, std::vector> + * @tparam IdxT + * @return std::tuple, std::vector, std::vector> */ -template -inline std::tuple, std::vector, std::vector> COO_Matrix::getDataToCSR() +template +inline std::tuple, std::vector, std::vector> COO_Matrix::getDataToCSR() { if (!this->isSorted()) this->sortSparse(); - std::vector rowsizevec(this->rows_size_ + 1, 0); - Intdx counter = 0; - for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) + std::vector rowsizevec(this->rows_size_ + 1, 0); + IdxT counter = 0; + for (IdxT i = 0; i < static_cast(rowsizevec.size() - 1); i++) { rowsizevec[i + 1] = rowsizevec[i]; - while (counter < static_cast(this->row_indexes_.size()) && i == this->row_indexes_[counter]) + while (counter < static_cast(this->row_indexes_.size()) && i == this->row_indexes_[counter]) { rowsizevec[i+1]++; counter++; @@ -178,19 +178,19 @@ inline std::tuple, std::vector, std::vector> * * * @tparam ScalarT - * @tparam Intdx - * @return std::vector + * @tparam IdxT + * @return std::vector */ -template -inline std::vector COO_Matrix::getCSRRowData() +template +inline std::vector COO_Matrix::getCSRRowData() { if (!this->isSorted()) this->sortSparse(); - std::vector rowsizevec(this->rows_size_ + 1, 0); - Intdx counter = 0; - for (Intdx i = 0; i < static_cast(rowsizevec.size() - 1); i++) + std::vector rowsizevec(this->rows_size_ + 1, 0); + IdxT counter = 0; + for (IdxT i = 0; i < static_cast(rowsizevec.size() - 1); i++) { rowsizevec[i + 1] = rowsizevec[i]; - while (counter < static_cast(this->row_indexes_.size()) && i == this->row_indexes_[counter]) + while (counter < static_cast(this->row_indexes_.size()) && i == this->row_indexes_[counter]) { rowsizevec[i+1]++; counter++; @@ -203,25 +203,25 @@ inline std::vector COO_Matrix::getCSRRowData() * @brief Given set of vector data it will set the values_ into the matrix * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT * @param r * @param c * @param v */ -template -inline void COO_Matrix::setValues(std::vector r, std::vector c, std::vector v) +template +inline void COO_Matrix::setValues(std::vector r, std::vector c, std::vector v) { //sort input this->sortSparseCOO(r, c, v); //Duplicated with axpy. Could replace with function depdent on lambda expression - Intdx aiter = 0; + IdxT aiter = 0; //iterate for all current values_ in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes_.size()); i++) + for (IdxT i = 0; i < static_cast(this->row_indexes_.size()); i++) { //pushback values_ when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes_[i] || (r[aiter] == this->row_indexes_[i] && c[aiter] < this->column_indexes_[i]))) + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes_[i] || (r[aiter] == this->row_indexes_[i] && c[aiter] < this->column_indexes_[i]))) { this->row_indexes_.push_back(r[aiter]); this->column_indexes_.push_back(c[aiter]); @@ -229,7 +229,7 @@ inline void COO_Matrix::setValues(std::vector r, std::vec this->checkIncreaseSize(r[aiter], c[aiter]); aiter++; } - if (aiter >= static_cast(r.size())) + if (aiter >= static_cast(r.size())) { break; } @@ -242,7 +242,7 @@ inline void COO_Matrix::setValues(std::vector r, std::vec } } //push back rest that was not found sorted - for (Intdx i = aiter; i < static_cast(r.size()); i++) + for (IdxT i = aiter; i < static_cast(r.size()); i++) { this->row_indexes_.push_back(r[i]); this->column_indexes_.push_back(c[i]); @@ -259,12 +259,12 @@ inline void COO_Matrix::setValues(std::vector r, std::vec * @brief BLAS axpy operation on another COO matrix. Will sort both matrices before acting * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT * @param alpha * @param a */ -template -inline void COO_Matrix::axpy(ScalarT alpha, COO_Matrix& a) +template +inline void COO_Matrix::axpy(ScalarT alpha, COO_Matrix& a) { if (alpha == 0) { @@ -279,9 +279,9 @@ inline void COO_Matrix::axpy(ScalarT alpha, COO_Matrix&, std::vector&, std::vector&> tpm = a.getEntries(); + IdxT m = 0; + IdxT n = 0; + std::tuple&, std::vector&, std::vector&> tpm = a.getEntries(); const auto& [r, c, val] = tpm; std::tie(m,n) = a.getDimensions(); @@ -289,12 +289,12 @@ inline void COO_Matrix::axpy(ScalarT alpha, COO_Matrixrows_size_ = this->rows_size_ > m ? this->rows_size_ : m; this->columns_size_ = this->columns_size_ > n ? this->columns_size_ : n; - Intdx aiter = 0; + IdxT aiter = 0; //iterate for all current values_ in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes_.size()); i++) + for (IdxT i = 0; i < static_cast(this->row_indexes_.size()); i++) { //pushback values_ when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes_[i] || (r[aiter] == this->row_indexes_[i] && c[aiter] < this->column_indexes_[i]))) + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes_[i] || (r[aiter] == this->row_indexes_[i] && c[aiter] < this->column_indexes_[i]))) { this->row_indexes_.push_back(r[aiter]); this->column_indexes_.push_back(c[aiter]); @@ -303,7 +303,7 @@ inline void COO_Matrix::axpy(ScalarT alpha, COO_MatrixcheckIncreaseSize(r[aiter], c[aiter]); aiter++; } - if (aiter >= static_cast(r.size())) + if (aiter >= static_cast(r.size())) { break; } @@ -316,7 +316,7 @@ inline void COO_Matrix::axpy(ScalarT alpha, COO_Matrix(r.size()); i++) + for (IdxT i = aiter; i < static_cast(r.size()); i++) { this->row_indexes_.push_back(r[i]); this->column_indexes_.push_back(c[i]); @@ -332,14 +332,14 @@ inline void COO_Matrix::axpy(ScalarT alpha, COO_Matrix -inline void COO_Matrix::axpy(ScalarT alpha, std::vector r, std::vector c, std::vector v) +template +inline void COO_Matrix::axpy(ScalarT alpha, std::vector r, std::vector c, std::vector v) { if (alpha == 0) return; @@ -351,12 +351,12 @@ inline void COO_Matrix::axpy(ScalarT alpha, std::vector r //sort input this->sortSparseCOO(r, c, v); - Intdx aiter = 0; + IdxT aiter = 0; //iterate for all current values_ in matrix - for (Intdx i = 0; i < static_cast(this->row_indexes_.size()); i++) + for (IdxT i = 0; i < static_cast(this->row_indexes_.size()); i++) { //pushback values_ when they are not in current matrix - while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes_[i] || (r[aiter] == this->row_indexes_[i] && c[aiter] < this->column_indexes_[i]))) + while(aiter < static_cast(r.size()) && (r[aiter] < this->row_indexes_[i] || (r[aiter] == this->row_indexes_[i] && c[aiter] < this->column_indexes_[i]))) { this->row_indexes_.push_back(r[aiter]); this->column_indexes_.push_back(c[aiter]); @@ -365,7 +365,7 @@ inline void COO_Matrix::axpy(ScalarT alpha, std::vector r this->checkIncreaseSize(r[aiter], c[aiter]); aiter++; } - if (aiter >= static_cast(r.size())) + if (aiter >= static_cast(r.size())) { break; } @@ -378,7 +378,7 @@ inline void COO_Matrix::axpy(ScalarT alpha, std::vector r } } //push back rest that was not found sorted_ - for (Intdx i = aiter; i < static_cast(r.size()); i++) + for (IdxT i = aiter; i < static_cast(r.size()); i++) { this->row_indexes_.push_back(r[i]); this->column_indexes_.push_back(c[i]); @@ -394,11 +394,11 @@ inline void COO_Matrix::axpy(ScalarT alpha, std::vector r * @brief Scale all values_ * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT * @param alpha */ -template -inline void COO_Matrix::scal(ScalarT alpha) +template +inline void COO_Matrix::scal(ScalarT alpha) { for (auto i = this->values_.begin(); i < this->values_.end(); i++) { @@ -410,11 +410,11 @@ inline void COO_Matrix::scal(ScalarT alpha) * @brief Frobenius Norm of the Matrix * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT * @return ScalarT */ -template -inline ScalarT COO_Matrix::frobnorm() +template +inline ScalarT COO_Matrix::frobnorm() { ScalarT totsum = 0.0; for (auto i = this->values_.begin(); i < this->values_.end(); i++) @@ -428,12 +428,12 @@ inline ScalarT COO_Matrix::frobnorm() * @brief Permutate the matrix to a different one. Only changes the coordinates * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT * @param row_perm * @param col_perm */ -template -inline void COO_Matrix::permutation(std::vector row_perm, std::vector col_perm) +template +inline void COO_Matrix::permutation(std::vector row_perm, std::vector col_perm) { assert(row_perm.size() = this->rows_size_); assert(col_perm.size() = this->columns_size_); @@ -452,14 +452,14 @@ inline void COO_Matrix::permutation(std::vector row_perm, * if size is shrinking and value is to be removed the negative one * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT * @param row_perm size of m * @param col_perm size of n * @param m * @param n */ -template -inline void COO_Matrix::permutationSizeMap(std::vector row_perm, std::vector col_perm, Intdx m, Intdx n) +template +inline void COO_Matrix::permutationSizeMap(std::vector row_perm, std::vector col_perm, IdxT m, IdxT n) { assert(row_perm.size() == this->rows_size_); assert(col_perm.size() == this->columns_size_); @@ -486,10 +486,10 @@ inline void COO_Matrix::permutationSizeMap(std::vector ro * @brief Turn matrix into the zero matrix. Does not actual delete memory * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT */ -template -inline void COO_Matrix::zeroMatrix() +template +inline void COO_Matrix::zeroMatrix() { //resize doesn't effect capacity if smaller this->column_indexes_.resize(0); @@ -498,12 +498,12 @@ inline void COO_Matrix::zeroMatrix() this->sorted_ = true; } -template -inline void COO_Matrix::identityMatrix(Intdx n) +template +inline void COO_Matrix::identityMatrix(IdxT n) { //Reset Matrix this->zeroMatrix(); - for (Intdx i = 0; i < n; i++) + for (IdxT i = 0; i < n; i++) { this->column_indexes_[i] = i; this->row_indexes_[i] = i; @@ -516,41 +516,41 @@ inline void COO_Matrix::identityMatrix(Intdx n) * @brief Restructure the sparse matrix for faster accesses and modifications * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT */ -template -inline void COO_Matrix::sortSparse() +template +inline void COO_Matrix::sortSparse() { this->sortSparseCOO(this->row_indexes_, this->column_indexes_, this->values_); this->sorted_ = true; } -template -inline bool COO_Matrix::isSorted() +template +inline bool COO_Matrix::isSorted() { return this->sorted_; } -template -inline Intdx COO_Matrix::nnz() +template +inline IdxT COO_Matrix::nnz() { - return static_cast(this->values_.size); + return static_cast(this->values_.size); } -template -inline std::tuple COO_Matrix::getDimensions() +template +inline std::tuple COO_Matrix::getDimensions() { - return std::tuple(this->rows_size_, this->columns_size_); + return std::tuple(this->rows_size_, this->columns_size_); } /** * @brief Print matrix that is sorted_ * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT */ -template -inline void COO_Matrix::printMatrix() +template +inline void COO_Matrix::printMatrix() { if (this->sorted_ == false) { @@ -573,18 +573,18 @@ inline void COO_Matrix::printMatrix() * * Assumes rows and columns are sorted_ * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT * @param r - * @return Intdx + * @return IdxT */ -template -inline Intdx COO_Matrix::indexStartRow(const std::vector &rows, Intdx r) +template +inline IdxT COO_Matrix::indexStartRow(const std::vector &rows, IdxT r) { //Specialized Binary Search for Lowest Row - Intdx i1 = 0; - Intdx i2 = rows->size()-1; - Intdx m_smallest = -1; - Intdx m = -1; + IdxT i1 = 0; + IdxT i2 = rows->size()-1; + IdxT m_smallest = -1; + IdxT m = -1; while (i1 <= i2) { m = (i2 + i1) / 2; @@ -616,21 +616,21 @@ inline Intdx COO_Matrix::indexStartRow(const std::vector * @brief Basic binary search * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT * @param rows * @param columns * @param ri * @param ci - * @return Intdx + * @return IdxT */ -template -inline Intdx COO_Matrix::sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, Intdx ri, Intdx ci) +template +inline IdxT COO_Matrix::sparseCordBinarySearch(const std::vector &rows, const std::vector &columns, IdxT ri, IdxT ci) { assert(rows.size() == columns.size()); //basic binary search - Intdx i1 = 0; - Intdx i2 = rows.size()-1; - Intdx m = 0; + IdxT i1 = 0; + IdxT i2 = rows.size()-1; + IdxT m = 0; while (i1 <= i2) { m = (i2 + i1) / 2; @@ -660,8 +660,8 @@ inline Intdx COO_Matrix::sparseCordBinarySearch(const std::vecto return m; } -template -inline bool COO_Matrix::checkIncreaseSize(Intdx r, Intdx c) +template +inline bool COO_Matrix::checkIncreaseSize(IdxT r, IdxT c) { bool changed = false; if (r + 1 > this->rows_size_) @@ -684,13 +684,13 @@ inline bool COO_Matrix::checkIncreaseSize(Intdx r, Intdx c) * @todo simple setup. Should add stable sorting since list are pre-sorted_ * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT * @param rows * @param columns * @param values_ */ -template -inline void COO_Matrix::sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &vals) +template +inline void COO_Matrix::sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &vals) { //index based sort code @@ -726,8 +726,8 @@ inline void COO_Matrix::sortSparseCOO(std::vector &rows, } } -template -inline COO_Matrix::COO_Matrix(std::vector r, std::vector c, std::vector v, Intdx m, Intdx n) +template +inline COO_Matrix::COO_Matrix(std::vector r, std::vector c, std::vector v, IdxT m, IdxT n) { this->values_ = v; this->row_indexes_ = r; @@ -737,30 +737,30 @@ inline COO_Matrix::COO_Matrix(std::vector r, std::vector< this->sorted_ = false; } -template -inline COO_Matrix::COO_Matrix(Intdx m, Intdx n) +template +inline COO_Matrix::COO_Matrix(IdxT m, IdxT n) { this->rows_size_ = m; this->columns_size_ = n; this->values_ = std::vector(); - this->row_indexes_ = std::vector(); - this->column_indexes_ = std::vector(); + this->row_indexes_ = std::vector(); + this->column_indexes_ = std::vector(); this->sorted_ = false; } -template -inline COO_Matrix::COO_Matrix() +template +inline COO_Matrix::COO_Matrix() { this->rows_size_ = 0; this->columns_size_ = 0; this->values_ = std::vector(); - this->row_indexes_ = std::vector(); - this->column_indexes_ = std::vector(); + this->row_indexes_ = std::vector(); + this->column_indexes_ = std::vector(); this->sorted_ = false; } -template -COO_Matrix::~COO_Matrix() +template +COO_Matrix::~COO_Matrix() { } From 991dca1e44ec5db31cea7b72289a49e7afb8cb1f Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Fri, 7 Feb 2025 19:40:01 -0500 Subject: [PATCH 24/52] Method to convert Dense matriz to COO. --- .../LinearAlgebra/DenseTest/DenseTest.cpp | 4 +- src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp | 116 +++++++++++++----- 2 files changed, 89 insertions(+), 31 deletions(-) diff --git a/examples/LinearAlgebra/DenseTest/DenseTest.cpp b/examples/LinearAlgebra/DenseTest/DenseTest.cpp index 3a3878d75..8b5e27bd3 100644 --- a/examples/LinearAlgebra/DenseTest/DenseTest.cpp +++ b/examples/LinearAlgebra/DenseTest/DenseTest.cpp @@ -19,8 +19,8 @@ int main() val += 1.0; } } - std::cout << "Dense matrix test output\n"; - A.printMatrix(); + A.printMatrix("Dense matrix test output"); + (A.getValuesCOO())->printMatrix(); return fail; } diff --git a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp index 97f33b55c..c371098db 100644 --- a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp +++ b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp @@ -4,6 +4,7 @@ #include #include #include +#include /** * @brief Class to provide dense matrices. @@ -15,25 +16,29 @@ namespace GridKit { namespace LinearAlgebra { -template +template class DenseMatrix { private: - Intdx rows_size_; - Intdx columns_size_; + IdxT rows_size_; + IdxT columns_size_; std::vector values_; - + COO_Matrix values_COO_; + bool values_changed_ = false; + bool sparsified_ = false; public: // Constructors and destructors - DenseMatrix(const Intdx rows_size, const Intdx columns_size); + DenseMatrix(const IdxT rows_size, const IdxT columns_size); ~DenseMatrix(); // Getters and setters - ScalarT getValue(const Intdx i, const Intdx j) const; - void setValue(const Intdx i, const Intdx j, const ScalarT value); + ScalarT getValue(const IdxT i, const IdxT j) const; + void setValue(const IdxT i, const IdxT j, const ScalarT value); std::vector* getValues(); + COO_Matrix* getValuesCOO(); // Utilities + void toCOO(); void printMatrix(std::string name=""); // Purposefully not defining BLAS operations. This class should not be used @@ -44,13 +49,14 @@ class DenseMatrix * @brief DenseMatrix constructor * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT */ -template -DenseMatrix::DenseMatrix(const Intdx rows_size, const Intdx columns_size) : +template +DenseMatrix::DenseMatrix(const IdxT rows_size, const IdxT columns_size) : rows_size_(rows_size), columns_size_(columns_size), - values_(rows_size*columns_size, 0) + values_(rows_size*columns_size, 0), + values_COO_(rows_size, columns_size) { } @@ -59,10 +65,10 @@ DenseMatrix::DenseMatrix(const Intdx rows_size, const Intdx colu * @brief DenseMatrix single value getter * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT */ -template -inline ScalarT DenseMatrix::getValue(const Intdx i, const Intdx j) const +template +inline ScalarT DenseMatrix::getValue(const IdxT i, const IdxT j) const { assert(i < this->columns_size_); assert(j < this->rows_size_); @@ -73,41 +79,93 @@ inline ScalarT DenseMatrix::getValue(const Intdx i, const Intdx * @brief DenseMatrix single value setter * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT */ -template -inline void DenseMatrix::setValue(const Intdx i, const Intdx j, const ScalarT value) +template +inline void DenseMatrix::setValue(const IdxT i, const IdxT j, const ScalarT value) { assert(i < this->columns_size_); assert(j < this->rows_size_); this->values_[j*rows_size_+i] = value; + values_changed_ = true; } /** - * @brief DenseMatrix single value setter + * @brief DenseMatrix getter for all values stored as a vector * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT */ -template -inline std::vector* DenseMatrix::getValues() +template +inline std::vector* DenseMatrix::getValues() { return &(this->values_); } +/** + * @brief DenseMatrix getter for all values stored as a COO sparse matrix + * + * @tparam ScalarT + * @tparam IdxT + */ +template +inline COO_Matrix* DenseMatrix::getValuesCOO() +{ + if (!sparsified_ || values_changed_) + { + this->toCOO(); + } + return &(this->values_COO_); +} + +/** + * @brief Dense matrix conversion to COO form + * + * @tparam ScalarT + * @tparam IdxT + */ +template +inline void DenseMatrix::toCOO() +{ + if (!sparsified_ || values_changed_) + { + IdxT nnz = 0; + std::vector rcord; + std::vector ccord; + std::vector vals; + for (IdxT j = 0; j < this->columns_size_; ++j) + { + for (IdxT i = 0; i < this->rows_size_; ++i) + { + ScalarT value = this->values_[j*rows_size_+i]; + if (value > std::numeric_limits::epsilon()) + { + nnz++; + rcord.push_back(i); + ccord.push_back(j); + vals.push_back(value); + } + } + } + values_COO_.setValues(rcord, ccord, vals); + sparsified_ = true; + values_changed_ = false; + } +} + /** * @brief Print matrix * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT */ -template -inline void DenseMatrix::printMatrix(std::string name) +template +inline void DenseMatrix::printMatrix(std::string name) { std::cout << "Dense matrix: " << name << "\n"; - for (size_t i = 0; i < this->rows_size_; ++i) + for (IdxT i = 0; i < this->rows_size_; ++i) { - for (size_t j = 0; j < this->columns_size_; ++j) + for (IdxT j = 0; j < this->columns_size_; ++j) { std::cout << this->values_[j*rows_size_+i] << " "; } @@ -119,10 +177,10 @@ inline void DenseMatrix::printMatrix(std::string name) * @brief DenseMatrix destructor * * @tparam ScalarT - * @tparam Intdx + * @tparam IdxT */ -template -DenseMatrix::~DenseMatrix() +template +DenseMatrix::~DenseMatrix() { } From 7f5d49f66be395dcea08cc729211259ead39a688 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 10 Feb 2025 10:32:55 -0500 Subject: [PATCH 25/52] Use DenseMatrix to store the Jacobians in Enzyme vector example. --- examples/Enzyme/Standalone/EnzymeVector.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/examples/Enzyme/Standalone/EnzymeVector.cpp b/examples/Enzyme/Standalone/EnzymeVector.cpp index 51dca61a5..4deb55bd6 100644 --- a/examples/Enzyme/Standalone/EnzymeVector.cpp +++ b/examples/Enzyme/Standalone/EnzymeVector.cpp @@ -26,19 +26,20 @@ void square(int N, double* x, double* y) { } } -void dsquare_ref(int N, double* x, double* y, double* dy) { +void dsquare_ref(int N, double* x, double* y, DenseMatrix& dy) { for (int idy = 0; idy < N; ++idy) { for (int idx = 0; idx < N; ++idx) { - dy[idy*N+idx] = 0.0; + dy.setValue(idx, idy, 0.0); // For clarity, but unnecessary. The DenseMatrix + // constructor initializes all values to 0 if (idx == idy) - dy[idy*N+idx] = dsquare_ref_scalar(x[idx]); + dy.setValue(idx, idy, dsquare_ref_scalar(x[idx])); } } } -void dsquare(int N, double* x, double* y, double* dy) { +void dsquare(int N, double* x, double* y, DenseMatrix& dy) { double* v = new double[N]; double* d_y = new double[N]; for (int idy = 0; idy < N; ++idy) @@ -58,7 +59,7 @@ void dsquare(int N, double* x, double* y, double* dy) { // Store result for (int idx = 0; idx < N; ++idx) { - dy[idy*N+idx] = d_y[idx]; + dy.setValue(idx, idy, d_y[idx]); } } delete[] v; @@ -85,10 +86,10 @@ int main() square(x.size(), x.data(), sq.data()); // Reference Jacobian - dsquare_ref(x.size(), x.data(), sq.data(), (dsq_ref.getValues())->data()); + dsquare_ref(x.size(), x.data(), sq.data(), dsq_ref); // Enzyme Jacobian - dsquare(x.size(), x.data(), sq.data(), (dsq.getValues())->data()); + dsquare(x.size(), x.data(), sq.data(), dsq); // Check int fail = 0; From c918663eb7146b2cc67e5b03af85859527a856b8 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 10 Feb 2025 10:46:00 -0500 Subject: [PATCH 26/52] Typo fix in CMakeLists: mirco-->micro. --- examples/DistributedGeneratorTest/CMakeLists.txt | 2 +- examples/Microgrid/CMakeLists.txt | 4 ++-- examples/ScaleMicrogrid/CMakeLists.txt | 4 ++-- src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt | 4 ++-- src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/DistributedGeneratorTest/CMakeLists.txt b/examples/DistributedGeneratorTest/CMakeLists.txt index 41b124cb8..4a2616112 100644 --- a/examples/DistributedGeneratorTest/CMakeLists.txt +++ b/examples/DistributedGeneratorTest/CMakeLists.txt @@ -4,7 +4,7 @@ add_executable(dgtest DGTest.cpp) target_link_libraries(dgtest GRIDKIT::powerelec_disgen - GRIDKIT::powerelec_mircoline + GRIDKIT::powerelec_microline GRIDKIT::powerelec_microload GRIDKIT::solvers_dyn) diff --git a/examples/Microgrid/CMakeLists.txt b/examples/Microgrid/CMakeLists.txt index 77c59d753..b5f5d584a 100644 --- a/examples/Microgrid/CMakeLists.txt +++ b/examples/Microgrid/CMakeLists.txt @@ -4,10 +4,10 @@ add_executable(microgrid Microgrid.cpp) target_link_libraries(microgrid GRIDKIT::powerelec_disgen - GRIDKIT::powerelec_mircoline + GRIDKIT::powerelec_microline GRIDKIT::powerelec_microload GRIDKIT::solvers_dyn - GRIDKIT::powerelec_mircobusdq) + GRIDKIT::powerelec_microbusdq) add_test(NAME Microgrid COMMAND $) install(TARGETS microgrid RUNTIME DESTINATION bin) diff --git a/examples/ScaleMicrogrid/CMakeLists.txt b/examples/ScaleMicrogrid/CMakeLists.txt index d1822c587..bbd3890d6 100644 --- a/examples/ScaleMicrogrid/CMakeLists.txt +++ b/examples/ScaleMicrogrid/CMakeLists.txt @@ -4,10 +4,10 @@ add_executable(scalemicrogrid ScaleMicrogrid.cpp) target_link_libraries(scalemicrogrid GRIDKIT::powerelec_disgen - GRIDKIT::powerelec_mircoline + GRIDKIT::powerelec_microline GRIDKIT::powerelec_microload GRIDKIT::solvers_dyn - GRIDKIT::powerelec_mircobusdq) + GRIDKIT::powerelec_microbusdq) add_test(NAME ScaleMicrogrid COMMAND $) install(TARGETS scalemicrogrid RUNTIME DESTINATION bin) diff --git a/src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt b/src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt index 1bfb8dc3d..1006170f4 100644 --- a/src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt +++ b/src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_mircobusdq +gridkit_add_library(powerelec_microbusdq SOURCES MicrogridBusDQ.cpp OUTPUT_NAME - gridkit_powerelec_mircobusdq) \ No newline at end of file + gridkit_powerelec_microbusdq) \ No newline at end of file diff --git a/src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt b/src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt index d59cebb9c..1f0ad6f10 100644 --- a/src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt +++ b/src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_mircoline +gridkit_add_library(powerelec_microline SOURCES MicrogridLine.cpp OUTPUT_NAME - gridkit_powerelec_mircoline) \ No newline at end of file + gridkit_powerelec_microline) \ No newline at end of file From f11e460c3cb3029b99add01e6af7f1bdb74b6d70 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 10 Feb 2025 10:48:07 -0500 Subject: [PATCH 27/52] Minor formatting. --- examples/Enzyme/Library/CMakeLists.txt | 5 ++++- examples/Enzyme/Standalone/CMakeLists.txt | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/Enzyme/Library/CMakeLists.txt b/examples/Enzyme/Library/CMakeLists.txt index 72e346876..16b6601c8 100644 --- a/examples/Enzyme/Library/CMakeLists.txt +++ b/examples/Enzyme/Library/CMakeLists.txt @@ -1,3 +1,6 @@ -enzyme_add_executable(NAME EnzymeLibCheck SOURCES main.cpp Library.cpp) +enzyme_add_executable( + NAME EnzymeLibCheck + SOURCES main.cpp Library.cpp +) add_test(NAME "EnzymeLibCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibCheck) diff --git a/examples/Enzyme/Standalone/CMakeLists.txt b/examples/Enzyme/Standalone/CMakeLists.txt index 64350af6f..fe41dc744 100644 --- a/examples/Enzyme/Standalone/CMakeLists.txt +++ b/examples/Enzyme/Standalone/CMakeLists.txt @@ -1,13 +1,13 @@ enzyme_add_executable( NAME EnzymeStandaloneScalarCheck SOURCES EnzymeScalar.cpp - ) +) enzyme_add_executable( NAME EnzymeStandaloneVectorCheck SOURCES EnzymeVector.cpp LINK_LIBRARIES GRIDKIT::DenseMatrix - ) +) add_test(NAME "EnzymeStandaloneScalarCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneScalarCheck) add_test(NAME "EnzymeStandaloneVectorCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeStandaloneVectorCheck) From 4b39fe8ee356ec0bcc36447283bcc885a6a65914 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 10 Feb 2025 14:32:18 -0500 Subject: [PATCH 28/52] pragma once for COO_Matrix. --- src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp b/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp index 6d838cb76..a142e447f 100644 --- a/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp +++ b/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp @@ -1,4 +1,4 @@ - +#pragma once #include #include From 91e291c063e1f3d73721562a13d7abdaa1b66457 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 10 Feb 2025 14:33:05 -0500 Subject: [PATCH 29/52] Better way to ensure paths exist for INCLUDES in enzyme_add_executable. --- cmake/FindEnzyme.cmake | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmake/FindEnzyme.cmake b/cmake/FindEnzyme.cmake index bb3dfa345..834692af6 100644 --- a/cmake/FindEnzyme.cmake +++ b/cmake/FindEnzyme.cmake @@ -153,8 +153,9 @@ macro(enzyme_add_executable) endforeach() foreach(dir ${includes}) - list(APPEND INCLUDE_COMPILER_LIST "-I${dir}") - break() + if(EXISTS ${dir}) + list(APPEND INCLUDE_COMPILER_LIST "-I${dir}") + endif() endforeach() foreach(SRC ${enzyme_add_executable_SOURCES}) From de6cc7192fd27c5b5b901ed7da712332e017cf98 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 10 Feb 2025 15:57:05 -0500 Subject: [PATCH 30/52] Functional use of -Wl to link GridKit libraries with Enzyme examples. --- cmake/FindEnzyme.cmake | 57 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/cmake/FindEnzyme.cmake b/cmake/FindEnzyme.cmake index e253b09fc..32a0513ca 100644 --- a/cmake/FindEnzyme.cmake +++ b/cmake/FindEnzyme.cmake @@ -68,11 +68,49 @@ Author(s): ]] +# Get all propreties that cmake supports +if(NOT CMAKE_PROPERTY_LIST) + execute_process(COMMAND cmake --help-property-list OUTPUT_VARIABLE CMAKE_PROPERTY_LIST) + + # Convert command output into a CMake list + string(REGEX REPLACE ";" "\\\\;" CMAKE_PROPERTY_LIST "${CMAKE_PROPERTY_LIST}") + string(REGEX REPLACE "\n" ";" CMAKE_PROPERTY_LIST "${CMAKE_PROPERTY_LIST}") + list(REMOVE_DUPLICATES CMAKE_PROPERTY_LIST) +endif() + +function(print_properties) + message("CMAKE_PROPERTY_LIST = ${CMAKE_PROPERTY_LIST}") +endfunction() + +function(print_target_properties target) + if(NOT TARGET ${target}) + message(STATUS "There is no target named '${target}'") + return() + endif() + + foreach(property ${CMAKE_PROPERTY_LIST}) + string(REPLACE "" "${CMAKE_BUILD_TYPE}" property ${property}) + + # Fix https://stackoverflow.com/questions/32197663/how-can-i-remove-the-the-location-property-may-not-be-read-from-target-error-i + if(property STREQUAL "LOCATION" OR property MATCHES "^LOCATION_" OR property MATCHES "_LOCATION$") + continue() + endif() + + get_property(was_set TARGET ${target} PROPERTY ${property} SET) + if(was_set) + get_target_property(value ${target} ${property}) + message("${target} ${property} = ${value}") + endif() + endforeach() +endfunction() + find_package(Enzyme REQUIRED CONFIG PATHS ${ENZYME_DIR} ${ENZYME_DIR}/lib/cmake/Enzyme) message(STATUS "Enzyme configuration found: ${Enzyme_CONFIG}") +print_target_properties(ClangEnzymeFlags) +print_target_properties(LLDEnzymeFlags) find_library(ENZYME_LLVM_PLUGIN_LIBRARY NAMES @@ -112,11 +150,19 @@ macro(enzyme_add_executable) set(OBJS "") set(includes "${enzyme_add_executable_INCLUDE_DIRECTORIES}") + set(lib_sources "") foreach(lib ${enzyme_add_executable_LINK_LIBRARIES}) get_target_property(include ${lib} INCLUDE_DIRECTORIES) set(includes "${includes}" ${include}) + get_target_property(lib_source ${lib} SOURCES) + print_target_properties(${lib}) + string(FIND "${lib_source}" "TARGET" found) + if(NOT(${found} EQUAL -1)) + set(lib_sources "${lib_sources}" ${lib_source}) + endif() endforeach() + message(STATUS "Library sources: ${lib_sources}") foreach(dir ${includes}) if(EXISTS ${dir}) @@ -124,6 +170,13 @@ macro(enzyme_add_executable) endif() endforeach() + foreach(lib_source ${lib_sources}) + #if(TARGET ${lib_source}) + list(APPEND LINKER_FLAGS "-Wl,${lib_source}") + #endif() + endforeach() + message(STATUS "Linker flags: ${LINKER_FLAGS}") + foreach(SRC ${enzyme_add_executable_SOURCES}) set(PHASE0 "${CMAKE_CURRENT_SOURCE_DIR}/${SRC}") set(PHASE1 "${CMAKE_CURRENT_BINARY_DIR}/${enzyme_add_executable_NAME}_${SRC}_compile.o") @@ -160,9 +213,9 @@ macro(enzyme_add_executable) ) add_custom_command( - DEPENDS ${PHASE4} + DEPENDS ${PHASE4} ${lib_sources} OUTPUT ${PHASE5} - COMMAND ${CMAKE_CXX_COMPILER} ${PHASE4} -o ${PHASE5} + COMMAND ${CMAKE_CXX_COMPILER} ${LINKER_FLAGS} ${PHASE4} -o ${PHASE5} ) add_custom_target( From a25ed69d457757ded662a8aac7b4880e069c26c7 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 10 Feb 2025 16:00:43 -0500 Subject: [PATCH 31/52] Remove extra debug statements from FindEnzyme. --- cmake/FindEnzyme.cmake | 57 ++++-------------------------------------- 1 file changed, 5 insertions(+), 52 deletions(-) diff --git a/cmake/FindEnzyme.cmake b/cmake/FindEnzyme.cmake index 32a0513ca..a7d998c5a 100644 --- a/cmake/FindEnzyme.cmake +++ b/cmake/FindEnzyme.cmake @@ -68,49 +68,11 @@ Author(s): ]] -# Get all propreties that cmake supports -if(NOT CMAKE_PROPERTY_LIST) - execute_process(COMMAND cmake --help-property-list OUTPUT_VARIABLE CMAKE_PROPERTY_LIST) - - # Convert command output into a CMake list - string(REGEX REPLACE ";" "\\\\;" CMAKE_PROPERTY_LIST "${CMAKE_PROPERTY_LIST}") - string(REGEX REPLACE "\n" ";" CMAKE_PROPERTY_LIST "${CMAKE_PROPERTY_LIST}") - list(REMOVE_DUPLICATES CMAKE_PROPERTY_LIST) -endif() - -function(print_properties) - message("CMAKE_PROPERTY_LIST = ${CMAKE_PROPERTY_LIST}") -endfunction() - -function(print_target_properties target) - if(NOT TARGET ${target}) - message(STATUS "There is no target named '${target}'") - return() - endif() - - foreach(property ${CMAKE_PROPERTY_LIST}) - string(REPLACE "" "${CMAKE_BUILD_TYPE}" property ${property}) - - # Fix https://stackoverflow.com/questions/32197663/how-can-i-remove-the-the-location-property-may-not-be-read-from-target-error-i - if(property STREQUAL "LOCATION" OR property MATCHES "^LOCATION_" OR property MATCHES "_LOCATION$") - continue() - endif() - - get_property(was_set TARGET ${target} PROPERTY ${property} SET) - if(was_set) - get_target_property(value ${target} ${property}) - message("${target} ${property} = ${value}") - endif() - endforeach() -endfunction() - find_package(Enzyme REQUIRED CONFIG PATHS ${ENZYME_DIR} ${ENZYME_DIR}/lib/cmake/Enzyme) message(STATUS "Enzyme configuration found: ${Enzyme_CONFIG}") -print_target_properties(ClangEnzymeFlags) -print_target_properties(LLDEnzymeFlags) find_library(ENZYME_LLVM_PLUGIN_LIBRARY NAMES @@ -150,19 +112,17 @@ macro(enzyme_add_executable) set(OBJS "") set(includes "${enzyme_add_executable_INCLUDE_DIRECTORIES}") - set(lib_sources "") foreach(lib ${enzyme_add_executable_LINK_LIBRARIES}) get_target_property(include ${lib} INCLUDE_DIRECTORIES) set(includes "${includes}" ${include}) - get_target_property(lib_source ${lib} SOURCES) - print_target_properties(${lib}) - string(FIND "${lib_source}" "TARGET" found) + + get_target_property(libsource ${lib} SOURCES) + string(FIND "${libsource}" "TARGET" found) if(NOT(${found} EQUAL -1)) - set(lib_sources "${lib_sources}" ${lib_source}) + list(APPEND LINKER_FLAGS "-Wl,${libsource}") endif() endforeach() - message(STATUS "Library sources: ${lib_sources}") foreach(dir ${includes}) if(EXISTS ${dir}) @@ -170,13 +130,6 @@ macro(enzyme_add_executable) endif() endforeach() - foreach(lib_source ${lib_sources}) - #if(TARGET ${lib_source}) - list(APPEND LINKER_FLAGS "-Wl,${lib_source}") - #endif() - endforeach() - message(STATUS "Linker flags: ${LINKER_FLAGS}") - foreach(SRC ${enzyme_add_executable_SOURCES}) set(PHASE0 "${CMAKE_CURRENT_SOURCE_DIR}/${SRC}") set(PHASE1 "${CMAKE_CURRENT_BINARY_DIR}/${enzyme_add_executable_NAME}_${SRC}_compile.o") @@ -213,7 +166,7 @@ macro(enzyme_add_executable) ) add_custom_command( - DEPENDS ${PHASE4} ${lib_sources} + DEPENDS ${PHASE4} ${libsources} OUTPUT ${PHASE5} COMMAND ${CMAKE_CXX_COMPILER} ${LINKER_FLAGS} ${PHASE4} -o ${PHASE5} ) From 6b53a078a09939e6c7677194ccd0b2787377f4fd Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 10 Feb 2025 17:41:44 -0500 Subject: [PATCH 32/52] Progress on model autodiff (distributed generator case). --- examples/Enzyme/CMakeLists.txt | 1 + .../Enzyme/PowerElectronics/CMakeLists.txt | 7 ++ examples/Enzyme/PowerElectronics/main.cpp | 105 ++++++++++++++++++ 3 files changed, 113 insertions(+) create mode 100644 examples/Enzyme/PowerElectronics/CMakeLists.txt create mode 100644 examples/Enzyme/PowerElectronics/main.cpp diff --git a/examples/Enzyme/CMakeLists.txt b/examples/Enzyme/CMakeLists.txt index 794ec850c..f7ed45025 100644 --- a/examples/Enzyme/CMakeLists.txt +++ b/examples/Enzyme/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(Standalone) add_subdirectory(Library) +add_subdirectory(PowerElectronics) diff --git a/examples/Enzyme/PowerElectronics/CMakeLists.txt b/examples/Enzyme/PowerElectronics/CMakeLists.txt new file mode 100644 index 000000000..59c5eb445 --- /dev/null +++ b/examples/Enzyme/PowerElectronics/CMakeLists.txt @@ -0,0 +1,7 @@ +enzyme_add_executable( + NAME EnzymePowerElectronicsCheck + SOURCES main.cpp + LINK_LIBRARIES GRIDKIT::DenseMatrix GRIDKIT::powerelec_disgen +) + +add_test(NAME "EnzymePowerElectronicsCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymePowerElectronicsCheck) diff --git a/examples/Enzyme/PowerElectronics/main.cpp b/examples/Enzyme/PowerElectronics/main.cpp new file mode 100644 index 000000000..053aa2736 --- /dev/null +++ b/examples/Enzyme/PowerElectronics/main.cpp @@ -0,0 +1,105 @@ +#include +#include +#include +#include +#include + +using DenseMatrix = GridKit::LinearAlgebra::DenseMatrix; +using SparseMatrix = COO_Matrix; +using DG = ModelLib::DistributedGenerator; +using DGParameters = ModelLib::DistributedGeneratorParameters; + +//int enzyme_dupnoneed; +//int enzyme_dup; +//int enzyme_const; +//void __enzyme_fwddiff(void*, ...); +// +//template +//void wrapper(T* obj, double* res) { +// obj->evaluateResidual(); +// res = (obj->getResidual()).data(); +//} +// +//template +//SparseMatrix* EnzymeModelJacobian(T* model) { +// int N = model->size(); +// DenseMatrix Jac(N, N); +// double* v = new double[N]; +// double* res = new double[N]; +// double* d_res = new double[N]; +// for (int idy = 0; idy < N; ++idy) +// { +// // Elementary vector for Jacobian-vector product +// for (int idx = 0; idx < N; ++idx) +// { +// v[idx] = 0.0; +// } +// v[idy] = 1.0; +// +// // Autodiff +// __enzyme_fwddiff((void*)wrapper, +// enzyme_dup, model, v, +// enzyme_dupnoneed, res, d_res); +// +// // Store result +// for (int idx = 0; idx < N; ++idx) +// { +// Jac.setValue(idx, idy, d_res[idx]); +// } +// } +// +// delete[] v; +// delete[] res; +// delete[] d_res; +// +// return Jac.getValuesCOO(); +//} + +int main() { + // Model + DGParameters parms; + parms.wb_ = 2.0*M_PI*50.0; + parms.wc_ = 31.41; + parms.mp_ = 9.4e-5; + parms.Vn_ = 380.0; + parms.nq_ = 1.3e-3; + parms.F_ = 0.75; + parms.Kiv_ = 420.0; + parms.Kpv_ = 0.1; + parms.Kic_ = 2.0e4; + parms.Kpc_ = 15.0; + parms.Cf_ = 5.0e-5; + parms.rLf_ = 0.1; + parms.Lf_ = 1.35e-3; + parms.rLc_ = 0.03; + parms.Lc_ = 0.35e-3; + DG *dg = new DG(0, parms, true); + dg->allocate(); + dg->initialize(); + dg->updateTime(0.0, 0.0); + + // Residual evaluation and reference Jacobian + dg->evaluateResidual(); + dg->evaluateJacobian(); + SparseMatrix Jacobian_ref = dg->getJacobian(); + + //// Enzyme Jacobian + //SparseMatrix* Jacobian = EnzymeModelJacobian(dg); + + // Check + int fail = 0; + bool verbose = true; + if (verbose) + { + //std::cout << "Autodiff Jacobian\n"; + //Jacobian->printMatrix(); + std::cout << "Reference Jacobian\n"; + Jacobian_ref.printMatrix(); + } + std::cout << "Status: " << fail << "\n"; + + // Cleanup + delete dg; + return fail; + +} From 4e48386dd43e7c911d1259e28015d4e2f2b23904 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 10 Feb 2025 20:41:28 -0500 Subject: [PATCH 33/52] Attempts with DisctributedGenerator autodiff. --- examples/Enzyme/PowerElectronics/main.cpp | 110 ++++++++++++---------- 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/examples/Enzyme/PowerElectronics/main.cpp b/examples/Enzyme/PowerElectronics/main.cpp index 053aa2736..50fc3421c 100644 --- a/examples/Enzyme/PowerElectronics/main.cpp +++ b/examples/Enzyme/PowerElectronics/main.cpp @@ -9,51 +9,50 @@ using SparseMatrix = COO_Matrix; using DG = ModelLib::DistributedGenerator; using DGParameters = ModelLib::DistributedGeneratorParameters; -//int enzyme_dupnoneed; -//int enzyme_dup; -//int enzyme_const; -//void __enzyme_fwddiff(void*, ...); -// -//template -//void wrapper(T* obj, double* res) { -// obj->evaluateResidual(); -// res = (obj->getResidual()).data(); -//} -// -//template -//SparseMatrix* EnzymeModelJacobian(T* model) { -// int N = model->size(); -// DenseMatrix Jac(N, N); -// double* v = new double[N]; -// double* res = new double[N]; -// double* d_res = new double[N]; -// for (int idy = 0; idy < N; ++idy) -// { -// // Elementary vector for Jacobian-vector product -// for (int idx = 0; idx < N; ++idx) -// { -// v[idx] = 0.0; -// } -// v[idy] = 1.0; -// -// // Autodiff -// __enzyme_fwddiff((void*)wrapper, -// enzyme_dup, model, v, -// enzyme_dupnoneed, res, d_res); -// -// // Store result -// for (int idx = 0; idx < N; ++idx) -// { -// Jac.setValue(idx, idy, d_res[idx]); -// } -// } -// -// delete[] v; -// delete[] res; -// delete[] d_res; -// -// return Jac.getValuesCOO(); -//} +int enzyme_dupnoneed; +int enzyme_dup; +int enzyme_const; + +template +void __enzyme_fwddiff(void*, int, T*, double*, int, T*, double*); + +template +void wrapper(T* model, double* res) { + model->evaluateResidual(); + res = (model->getResidual()).data(); +} + +template +void EnzymeModelJacobian(T* model, DenseMatrix& jac) { + int N = model->size(); + T d_model(*model); + double* v = new double[N]; + double* d_res = new double[N]; + for (int idy = 0; idy < N; ++idy) + { + // Elementary vector for Jacobian-vector product + for (int idx = 0; idx < N; ++idx) + { + v[idx] = 0.0; + } + v[idy] = 1.0; + + //// Autodiff + //__enzyme_fwddiff((void*)wrapper, + // enzyme_dup, model, v, + // enzyme_dupnoneed, &d_model, d_res); + + // Store result + for (int idx = 0; idx < N; ++idx) + { + //std::cout << "i = " << idx << ", j = " << idy << ", d_res = " << d_res[idx] << "\n"; + jac.setValue(idx, idy, d_res[idx]); + } + } + + delete[] v; + delete[] d_res; +} int main() { // Model @@ -81,20 +80,29 @@ int main() { // Residual evaluation and reference Jacobian dg->evaluateResidual(); dg->evaluateJacobian(); - SparseMatrix Jacobian_ref = dg->getJacobian(); + std::vector y = dg->y(); + std::vector yp = dg->yp(); + std::vector res = dg->getResidual(); + SparseMatrix jac_ref = dg->getJacobian(); - //// Enzyme Jacobian - //SparseMatrix* Jacobian = EnzymeModelJacobian(dg); + // Enzyme Jacobian + DenseMatrix jac_autodiff(dg->size(), dg->size()); + EnzymeModelJacobian(dg, jac_autodiff); + SparseMatrix* jac_COO = jac_autodiff.getValuesCOO(); // Check int fail = 0; bool verbose = true; if (verbose) { - //std::cout << "Autodiff Jacobian\n"; - //Jacobian->printMatrix(); + for (int idx = 0; idx < dg->size(); ++idx) + { + std::cout << "i = " << idx << ", y = " << y[idx] << ", yp = " << yp[idx] << ", res = " << res[idx] <<"\n"; + } + std::cout << "Autodiff Jacobian\n"; + jac_COO->printMatrix(); std::cout << "Reference Jacobian\n"; - Jacobian_ref.printMatrix(); + jac_ref.printMatrix(); } std::cout << "Status: " << fail << "\n"; From 7ba837eb82478835b9cad30e224eb0dc6034773f Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 10 Feb 2025 21:26:34 -0500 Subject: [PATCH 34/52] Name input for COO_Matrix printMatrix method. --- src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp b/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp index a142e447f..9a7b53c5a 100644 --- a/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp +++ b/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp @@ -68,7 +68,7 @@ class COO_Matrix std::tuple getDimensions(); - void printMatrix(); + void printMatrix(std::string name=""); static void sortSparseCOO(std::vector &rows, std::vector &columns, std::vector &vals); @@ -550,14 +550,14 @@ inline std::tuple COO_Matrix::getDimensions() * @tparam IdxT */ template -inline void COO_Matrix::printMatrix() +inline void COO_Matrix::printMatrix(std::string name) { if (this->sorted_ == false) { this->sortSparse(); } - std::cout << "Sparse COO Matrix\n"; + std::cout << "Sparse COO Matrix: " << name << "\n"; std::cout << "(x , y, value)\n"; for (size_t i = 0; i < this->values_.size(); i++) { From c7c9546bbbd9fef733d8a6261541a69863cbc7c7 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 10 Feb 2025 21:39:54 -0500 Subject: [PATCH 35/52] Bug fix: need to check abs(value) to sparsify DenseMatrix. --- src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp index c371098db..e37ac3c74 100644 --- a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp +++ b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp @@ -138,7 +138,7 @@ inline void DenseMatrix::toCOO() for (IdxT i = 0; i < this->rows_size_; ++i) { ScalarT value = this->values_[j*rows_size_+i]; - if (value > std::numeric_limits::epsilon()) + if (std::abs(value) > std::numeric_limits::epsilon()) { nnz++; rcord.push_back(i); From 7a42e5f1a7459c375cdae9048707ec6c78275349 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 10 Feb 2025 21:40:57 -0500 Subject: [PATCH 36/52] Working Enzyme derivative of DistributedGenerator with evalResidual copied over. Need to make it work when using member functions. --- examples/Enzyme/PowerElectronics/main.cpp | 103 ++++++++++++++++++---- 1 file changed, 84 insertions(+), 19 deletions(-) diff --git a/examples/Enzyme/PowerElectronics/main.cpp b/examples/Enzyme/PowerElectronics/main.cpp index 50fc3421c..8bbe49c7d 100644 --- a/examples/Enzyme/PowerElectronics/main.cpp +++ b/examples/Enzyme/PowerElectronics/main.cpp @@ -12,35 +12,99 @@ using DGParameters = ModelLib::DistributedGeneratorParameters; int enzyme_dupnoneed; int enzyme_dup; int enzyme_const; +void __enzyme_fwddiff(void*, ...); -template -void __enzyme_fwddiff(void*, int, T*, double*, int, T*, double*); +// Copy from DistributedGenerator::evaluateResidual +// Need to find a way to differentiate the member function directly +void evaluateResidual(double* y_, double* f_) +{ + constexpr double wb_ = 2.0*M_PI*50.0; + constexpr double wc_ = 31.41; + constexpr double mp_ = 9.4e-5; + constexpr double Vn_ = 380.0; + constexpr double nq_ = 1.3e-3; + constexpr double F_ = 0.75; + constexpr double Kiv_ = 420.0; + constexpr double Kpv_ = 0.1; + constexpr double Kic_ = 2.0e4; + constexpr double Kpc_ = 15.0; + constexpr double Cf_ = 5.0e-5; + constexpr double rLf_ = 0.1; + constexpr double Lf_ = 1.35e-3; + constexpr double rLc_ = 0.03; + constexpr double Lc_ = 0.35e-3; -template -void wrapper(T* model, double* res) { - model->evaluateResidual(); - res = (model->getResidual()).data(); + constexpr bool refframe_ = true; + + std::vector yp_(0); + + double omega = wb_ - mp_ * y_[4]; + if (refframe_) + { + f_[0] = omega - y_[0]; + } + else + { + f_[0] = 0.0; + } + + f_[1] = cos(y_[3]) * y_[14] - sin(y_[3]) * y_[15]; + f_[2] = sin(y_[3]) * y_[14] + cos(y_[3]) * y_[15]; + + double vbd_in = cos(y_[3]) * y_[1] + sin(y_[3]) * y_[2]; + double vbq_in = -sin(y_[3]) * y_[1] + cos(y_[3]) * y_[2]; + + f_[3] = -yp_[3] + omega - y_[0]; + f_[4] = -yp_[4] + wc_ * (y_[12] * y_[14] + y_[13] * y_[15] - y_[4]); + f_[5] = -yp_[5] + wc_ * (-y_[12] * y_[15] + y_[13] * y_[14] - y_[5]); + + double vod_star = Vn_ - nq_ * y_[5]; + double voq_star = 0.0; + + f_[6] = -yp_[6] + vod_star - y_[12]; + f_[7] = -yp_[7] + voq_star - y_[13]; + + double ild_star = F_ * y_[14] - wb_ * Cf_ * y_[13] + Kpv_ * (vod_star - y_[12]) + Kiv_ * y_[6]; + double ilq_star = F_ * y_[15] + wb_ * Cf_ * y_[12] + Kpv_ * (voq_star - y_[13]) + Kiv_ * y_[7]; + + f_[8] = -yp_[8] + ild_star - y_[10]; + f_[9] = -yp_[9] + ilq_star - y_[11]; + + double vid_star = -wb_ * Lf_ * y_[11] + Kpc_ * (ild_star - y_[10]) + Kic_ * y_[8]; + double viq_star = wb_ * Lf_ * y_[10] + Kpc_ * (ilq_star - y_[11]) + Kic_ * y_[9]; + + f_[10] = -yp_[10] - (rLf_ / Lf_) * y_[10] + omega * y_[11] + (vid_star - y_[12]) / Lf_; + f_[11] = -yp_[11] - (rLf_ / Lf_) * y_[11] - omega * y_[10] + (viq_star - y_[13]) / Lf_; + + f_[12] = -yp_[12] + omega * y_[13] + (y_[10] - y_[14]) / Cf_; + f_[13] = -yp_[13] - omega * y_[12] + (y_[11] - y_[15]) / Cf_; + + f_[14] = -yp_[14] - (rLc_ / Lc_) * y_[14] + omega * y_[15] + (y_[12] - vbd_in) / Lc_; + f_[15] = -yp_[15] - (rLc_ / Lc_) * y_[15] - omega * y_[14] + (y_[13] - vbq_in) / Lc_; } template void EnzymeModelJacobian(T* model, DenseMatrix& jac) { int N = model->size(); - T d_model(*model); + double* y = new double[N]; double* v = new double[N]; + double* res = new double[N]; double* d_res = new double[N]; for (int idy = 0; idy < N; ++idy) { // Elementary vector for Jacobian-vector product for (int idx = 0; idx < N; ++idx) { + y[idx] = (model->y())[idx]; + res[idx] = (model->getResidual())[idx]; v[idx] = 0.0; } v[idy] = 1.0; - //// Autodiff - //__enzyme_fwddiff((void*)wrapper, - // enzyme_dup, model, v, - // enzyme_dupnoneed, &d_model, d_res); + // Autodiff + __enzyme_fwddiff((void*)evaluateResidual, + enzyme_dup, y, v, + enzyme_dupnoneed, res, d_res); // Store result for (int idx = 0; idx < N; ++idx) @@ -50,7 +114,9 @@ void EnzymeModelJacobian(T* model, DenseMatrix& jac) { } } + delete[] y; delete[] v; + delete[] res; delete[] d_res; } @@ -95,14 +161,13 @@ int main() { bool verbose = true; if (verbose) { - for (int idx = 0; idx < dg->size(); ++idx) - { - std::cout << "i = " << idx << ", y = " << y[idx] << ", yp = " << yp[idx] << ", res = " << res[idx] <<"\n"; - } - std::cout << "Autodiff Jacobian\n"; - jac_COO->printMatrix(); - std::cout << "Reference Jacobian\n"; - jac_ref.printMatrix(); + //for (int idx = 0; idx < dg->size(); ++idx) + //{ + // std::cout << "i = " << idx << ", y = " << y[idx] << ", yp = " << yp[idx] << ", res = " << res[idx] <<"\n"; + //} + jac_autodiff.printMatrix("Autodiff Jacobian"); + jac_COO->printMatrix("Autodiff Jacobian"); + jac_ref.printMatrix("Reference Jacobian"); } std::cout << "Status: " << fail << "\n"; From 0096cf22e81c424da8805722a12781289973d18d Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Tue, 11 Feb 2025 10:22:50 -0500 Subject: [PATCH 37/52] Method to set DenseMatrix values from COO. --- examples/Enzyme/PowerElectronics/main.cpp | 11 +++-------- src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp | 18 ++++++++++++++++++ src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp | 2 +- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/examples/Enzyme/PowerElectronics/main.cpp b/examples/Enzyme/PowerElectronics/main.cpp index 8bbe49c7d..df8b83307 100644 --- a/examples/Enzyme/PowerElectronics/main.cpp +++ b/examples/Enzyme/PowerElectronics/main.cpp @@ -109,7 +109,6 @@ void EnzymeModelJacobian(T* model, DenseMatrix& jac) { // Store result for (int idx = 0; idx < N; ++idx) { - //std::cout << "i = " << idx << ", j = " << idy << ", d_res = " << d_res[idx] << "\n"; jac.setValue(idx, idy, d_res[idx]); } } @@ -150,24 +149,20 @@ int main() { std::vector yp = dg->yp(); std::vector res = dg->getResidual(); SparseMatrix jac_ref = dg->getJacobian(); + DenseMatrix jac_ref_dense(dg->size(), dg->size()); + jac_ref_dense.setValues(jac_ref); // Enzyme Jacobian DenseMatrix jac_autodiff(dg->size(), dg->size()); EnzymeModelJacobian(dg, jac_autodiff); - SparseMatrix* jac_COO = jac_autodiff.getValuesCOO(); // Check int fail = 0; bool verbose = true; if (verbose) { - //for (int idx = 0; idx < dg->size(); ++idx) - //{ - // std::cout << "i = " << idx << ", y = " << y[idx] << ", yp = " << yp[idx] << ", res = " << res[idx] <<"\n"; - //} jac_autodiff.printMatrix("Autodiff Jacobian"); - jac_COO->printMatrix("Autodiff Jacobian"); - jac_ref.printMatrix("Reference Jacobian"); + jac_ref_dense.printMatrix("Reference Jacobian"); } std::cout << "Status: " << fail << "\n"; diff --git a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp index e37ac3c74..bee75730d 100644 --- a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp +++ b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp @@ -34,6 +34,7 @@ class DenseMatrix // Getters and setters ScalarT getValue(const IdxT i, const IdxT j) const; void setValue(const IdxT i, const IdxT j, const ScalarT value); + void setValues(COO_Matrix values_COO); std::vector* getValues(); COO_Matrix* getValuesCOO(); @@ -90,6 +91,23 @@ inline void DenseMatrix::setValue(const IdxT i, const IdxT j, con values_changed_ = true; } +/** + * @brief DenseMatrix value setter from COO + * + * @tparam ScalarT + * @tparam IdxT + */ +template +inline void DenseMatrix::setValues(COO_Matrix values_COO) +{ + std::tuple&, std::vector&, std::vector&> entries = values_COO.getEntries(); + const auto [rcord, ccord, vals] = entries; + for (IdxT idx = 0; idx < values_COO.nnz(); ++idx) + { + this->setValue(rcord[idx], ccord[idx], vals[idx]); + } +} + /** * @brief DenseMatrix getter for all values stored as a vector * diff --git a/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp b/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp index 9a7b53c5a..b3a392290 100644 --- a/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp +++ b/src/LinearAlgebra/SparseMatrix/COO_Matrix.hpp @@ -534,7 +534,7 @@ inline bool COO_Matrix::isSorted() template inline IdxT COO_Matrix::nnz() { - return static_cast(this->values_.size); + return static_cast(this->values_.size()); } template From d7ba02df5e55eafd2218870069a75fb6b68b7570 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Tue, 11 Feb 2025 10:26:17 -0500 Subject: [PATCH 38/52] Using DenseMatrix form of reference Jacobian to check the answer. --- examples/Enzyme/PowerElectronics/main.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/examples/Enzyme/PowerElectronics/main.cpp b/examples/Enzyme/PowerElectronics/main.cpp index df8b83307..1dc57313c 100644 --- a/examples/Enzyme/PowerElectronics/main.cpp +++ b/examples/Enzyme/PowerElectronics/main.cpp @@ -159,6 +159,20 @@ int main() { // Check int fail = 0; bool verbose = true; + for (int idy = 0; idy < dg->size(); ++idy) + { + for (int idx = 0; idx < dg->size(); ++idx) + { + if (std::abs(jac_autodiff.getValue(idx, idy) - jac_ref_dense.getValue(idx, idy)) > std::numeric_limits::epsilon()) + { + fail++; + if (verbose) + { + std::cout << "Result incorrect at line = " << idy << ", column = " << idx << "\n"; + } + } + } + } if (verbose) { jac_autodiff.printMatrix("Autodiff Jacobian"); From 6dab218a0ab1eb6e47dce7954cbf5162e42536a0 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Tue, 11 Feb 2025 11:08:53 -0500 Subject: [PATCH 39/52] EnzymeLibCheck->EnzymeLibScalarCheck in preparation for a vector version. --- examples/Enzyme/Library/CMakeLists.txt | 7 +--- examples/Enzyme/Library/Library.cpp | 34 ------------------- examples/Enzyme/Library/Scalar/CMakeLists.txt | 6 ++++ .../{main.cpp => Scalar/EnzymeScalar.cpp} | 14 ++++---- .../Library/{ => Scalar}/EnzymeWrapper.hpp | 0 .../Enzyme/Library/Scalar/ScalarModel.cpp | 34 +++++++++++++++++++ .../{Library.hpp => Scalar/ScalarModel.hpp} | 6 ++-- 7 files changed, 51 insertions(+), 50 deletions(-) delete mode 100644 examples/Enzyme/Library/Library.cpp create mode 100644 examples/Enzyme/Library/Scalar/CMakeLists.txt rename examples/Enzyme/Library/{main.cpp => Scalar/EnzymeScalar.cpp} (60%) rename examples/Enzyme/Library/{ => Scalar}/EnzymeWrapper.hpp (100%) create mode 100644 examples/Enzyme/Library/Scalar/ScalarModel.cpp rename examples/Enzyme/Library/{Library.hpp => Scalar/ScalarModel.hpp} (81%) diff --git a/examples/Enzyme/Library/CMakeLists.txt b/examples/Enzyme/Library/CMakeLists.txt index 16b6601c8..d5a768c72 100644 --- a/examples/Enzyme/Library/CMakeLists.txt +++ b/examples/Enzyme/Library/CMakeLists.txt @@ -1,6 +1 @@ -enzyme_add_executable( - NAME EnzymeLibCheck - SOURCES main.cpp Library.cpp -) - -add_test(NAME "EnzymeLibCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibCheck) +add_subdirectory(Scalar) diff --git a/examples/Enzyme/Library/Library.cpp b/examples/Enzyme/Library/Library.cpp deleted file mode 100644 index eb9c7116e..000000000 --- a/examples/Enzyme/Library/Library.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "EnzymeWrapper.hpp" -#include "Library.hpp" -#include - -inline -double Model::square(double x) { - return x * x; -} - -void Model::setVariable(double x) { - x_ = x; -} - -void Model::evalFunction() { - f_ = square(x_); -} - -void Model::evalDerivative() { - Model dModel; - dModel.setVariable(1.0); - dfdx_ = __enzyme_fwddiff((double*)wrapper, enzyme_dup, this, &dModel); -} - -double Model::getVariable() const { - return x_; -} - -double Model::getFunctionValue() const { - return f_; -} - -double Model::getDerivativeValue() const { - return dfdx_; -} diff --git a/examples/Enzyme/Library/Scalar/CMakeLists.txt b/examples/Enzyme/Library/Scalar/CMakeLists.txt new file mode 100644 index 000000000..6dff430a6 --- /dev/null +++ b/examples/Enzyme/Library/Scalar/CMakeLists.txt @@ -0,0 +1,6 @@ +enzyme_add_executable( + NAME EnzymeLibScalarCheck + SOURCES EnzymeScalar.cpp ScalarModel.cpp +) + +add_test(NAME "EnzymeLibScalarCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibScalarCheck) diff --git a/examples/Enzyme/Library/main.cpp b/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp similarity index 60% rename from examples/Enzyme/Library/main.cpp rename to examples/Enzyme/Library/Scalar/EnzymeScalar.cpp index b63b1dea2..eaa3bcd5c 100644 --- a/examples/Enzyme/Library/main.cpp +++ b/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp @@ -1,16 +1,16 @@ #include #include -#include "Library.hpp" +#include "ScalarModel.hpp" int main() { int fail = 0; - Model model; + ScalarModel scalar_model; double var = 5.0; - model.setVariable(var); - model.evalFunction(); - model.evalDerivative(); - double sq = model.getFunctionValue(); - double dsq = model.getDerivativeValue(); + scalar_model.setVariable(var); + scalar_model.evalFunction(); + scalar_model.evalDerivative(); + double sq = scalar_model.getFunctionValue(); + double dsq = scalar_model.getDerivativeValue(); std::cout << "x = " << var << ", x^2 = " << sq << ", d(x^2)/dx = " << dsq << "\n"; if (std::abs(dsq - 2.0*var) > std::numeric_limits::epsilon()) diff --git a/examples/Enzyme/Library/EnzymeWrapper.hpp b/examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp similarity index 100% rename from examples/Enzyme/Library/EnzymeWrapper.hpp rename to examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp diff --git a/examples/Enzyme/Library/Scalar/ScalarModel.cpp b/examples/Enzyme/Library/Scalar/ScalarModel.cpp new file mode 100644 index 000000000..59651f493 --- /dev/null +++ b/examples/Enzyme/Library/Scalar/ScalarModel.cpp @@ -0,0 +1,34 @@ +#include "EnzymeWrapper.hpp" +#include "ScalarModel.hpp" +#include + +inline +double ScalarModel::square(double x) { + return x * x; +} + +void ScalarModel::setVariable(double x) { + x_ = x; +} + +void ScalarModel::evalFunction() { + f_ = square(x_); +} + +void ScalarModel::evalDerivative() { + ScalarModel d_scalar_model; + d_scalar_model.setVariable(1.0); + dfdx_ = __enzyme_fwddiff((double*)wrapper, enzyme_dup, this, &d_scalar_model); +} + +double ScalarModel::getVariable() const { + return x_; +} + +double ScalarModel::getFunctionValue() const { + return f_; +} + +double ScalarModel::getDerivativeValue() const { + return dfdx_; +} diff --git a/examples/Enzyme/Library/Library.hpp b/examples/Enzyme/Library/Scalar/ScalarModel.hpp similarity index 81% rename from examples/Enzyme/Library/Library.hpp rename to examples/Enzyme/Library/Scalar/ScalarModel.hpp index c74369dce..6b29e4872 100644 --- a/examples/Enzyme/Library/Library.hpp +++ b/examples/Enzyme/Library/Scalar/ScalarModel.hpp @@ -1,17 +1,17 @@ #pragma once -class Model { +class ScalarModel { private: double x_, f_, dfdx_; inline double square(double); public: - Model() {}; + ScalarModel() {}; void setVariable(double); void evalFunction(); void evalDerivative(); double getVariable() const; double getFunctionValue() const; double getDerivativeValue() const; - ~Model() {}; + ~ScalarModel() {}; }; From ef110ac877d9777430bebae0331395ac268e7c05 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Tue, 11 Feb 2025 11:23:39 -0500 Subject: [PATCH 40/52] Seemingly working EnzymeStandaloneVectorCheck using std::vector instead of double* in function calls. --- examples/Enzyme/Standalone/EnzymeVector.cpp | 38 ++++++++++----------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/examples/Enzyme/Standalone/EnzymeVector.cpp b/examples/Enzyme/Standalone/EnzymeVector.cpp index 4deb55bd6..c643328fe 100644 --- a/examples/Enzyme/Standalone/EnzymeVector.cpp +++ b/examples/Enzyme/Standalone/EnzymeVector.cpp @@ -7,7 +7,8 @@ using DenseMatrix = GridKit::LinearAlgebra::DenseMatrix; int enzyme_dupnoneed; int enzyme_dup; int enzyme_const; -void __enzyme_fwddiff(void*, ...); +void __enzyme_fwddiff(void*, int, std::vector, std::vector, + int, std::vector, std::vector*); inline double square_scalar(double x) { @@ -19,17 +20,17 @@ double dsquare_ref_scalar(double x) { return 2.0 * x; } -void square(int N, double* x, double* y) { - for (int idx = 0; idx < N; ++idx) +void square(std::vector x, std::vector y) { + for (int idx = 0; idx < x.size(); ++idx) { y[idx] = square_scalar(x[idx]); } } -void dsquare_ref(int N, double* x, double* y, DenseMatrix& dy) { - for (int idy = 0; idy < N; ++idy) +void dsquare_ref(std::vector x, std::vector y, DenseMatrix& dy) { + for (int idy = 0; idy < y.size(); ++idy) { - for (int idx = 0; idx < N; ++idx) + for (int idx = 0; idx < x.size(); ++idx) { dy.setValue(idx, idy, 0.0); // For clarity, but unnecessary. The DenseMatrix // constructor initializes all values to 0 @@ -39,31 +40,28 @@ void dsquare_ref(int N, double* x, double* y, DenseMatrix& dy) { } } -void dsquare(int N, double* x, double* y, DenseMatrix& dy) { - double* v = new double[N]; - double* d_y = new double[N]; - for (int idy = 0; idy < N; ++idy) +void dsquare(std::vector x, std::vector y, DenseMatrix& dy) { + std::vector v(x.size()); + std::vector d_y(y.size()); + for (int idy = 0; idy < y.size(); ++idy) { // Elementary vector for Jacobian-vector product - for (int idx = 0; idx < N; ++idx) + for (int idx = 0; idx < x.size(); ++idx) { v[idx] = 0.0; } v[idy] = 1.0; // Autodiff - __enzyme_fwddiff((void*)square, enzyme_const, N, - enzyme_dup, x, v, - enzyme_dupnoneed, y, d_y); + __enzyme_fwddiff((void*)square, enzyme_dup, x, v, + enzyme_dupnoneed, y, &d_y); // Store result - for (int idx = 0; idx < N; ++idx) + for (int idx = 0; idx < x.size(); ++idx) { dy.setValue(idx, idy, d_y[idx]); } } - delete[] v; - delete[] d_y; } int main() @@ -83,13 +81,13 @@ int main() } // Function evaluation - square(x.size(), x.data(), sq.data()); + square(x, sq); // Reference Jacobian - dsquare_ref(x.size(), x.data(), sq.data(), dsq_ref); + dsquare_ref(x, sq, dsq_ref); // Enzyme Jacobian - dsquare(x.size(), x.data(), sq.data(), dsq); + dsquare(x, sq, dsq); // Check int fail = 0; From 733b37d872ced6fc23b09eee975568aee7bdf546 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Tue, 11 Feb 2025 11:30:20 -0500 Subject: [PATCH 41/52] EnzymePowerElectronicsCheck also works with std::vector instead of double* in function calls. Simply needed to expand the formely variadic enzyme_fwddiff function. --- examples/Enzyme/PowerElectronics/main.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/examples/Enzyme/PowerElectronics/main.cpp b/examples/Enzyme/PowerElectronics/main.cpp index 1dc57313c..41d169e7b 100644 --- a/examples/Enzyme/PowerElectronics/main.cpp +++ b/examples/Enzyme/PowerElectronics/main.cpp @@ -12,11 +12,12 @@ using DGParameters = ModelLib::DistributedGeneratorParameters; int enzyme_dupnoneed; int enzyme_dup; int enzyme_const; -void __enzyme_fwddiff(void*, ...); +void __enzyme_fwddiff(void*, int, std::vector, std::vector, + int, std::vector, std::vector*); // Copy from DistributedGenerator::evaluateResidual // Need to find a way to differentiate the member function directly -void evaluateResidual(double* y_, double* f_) +void evaluateResidual(std::vector y_, std::vector f_) { constexpr double wb_ = 2.0*M_PI*50.0; constexpr double wc_ = 31.41; @@ -86,10 +87,10 @@ void evaluateResidual(double* y_, double* f_) template void EnzymeModelJacobian(T* model, DenseMatrix& jac) { int N = model->size(); - double* y = new double[N]; - double* v = new double[N]; - double* res = new double[N]; - double* d_res = new double[N]; + std::vector y(N); + std::vector v(N); + std::vector res(N); + std::vector d_res(N); for (int idy = 0; idy < N; ++idy) { // Elementary vector for Jacobian-vector product @@ -104,7 +105,7 @@ void EnzymeModelJacobian(T* model, DenseMatrix& jac) { // Autodiff __enzyme_fwddiff((void*)evaluateResidual, enzyme_dup, y, v, - enzyme_dupnoneed, res, d_res); + enzyme_dupnoneed, res, &d_res); // Store result for (int idx = 0; idx < N; ++idx) @@ -112,11 +113,6 @@ void EnzymeModelJacobian(T* model, DenseMatrix& jac) { jac.setValue(idx, idy, d_res[idx]); } } - - delete[] y; - delete[] v; - delete[] res; - delete[] d_res; } int main() { From 30e10656afaacb54422a3e4703d2423f9755afce Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Tue, 11 Feb 2025 13:50:55 -0500 Subject: [PATCH 42/52] Bug fix: Need to pass output vector as a reference. --- examples/Enzyme/Standalone/EnzymeVector.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/Enzyme/Standalone/EnzymeVector.cpp b/examples/Enzyme/Standalone/EnzymeVector.cpp index c643328fe..87df1d9c7 100644 --- a/examples/Enzyme/Standalone/EnzymeVector.cpp +++ b/examples/Enzyme/Standalone/EnzymeVector.cpp @@ -20,7 +20,7 @@ double dsquare_ref_scalar(double x) { return 2.0 * x; } -void square(std::vector x, std::vector y) { +void square(std::vector x, std::vector& y) { for (int idx = 0; idx < x.size(); ++idx) { y[idx] = square_scalar(x[idx]); @@ -32,8 +32,6 @@ void dsquare_ref(std::vector x, std::vector y, DenseMatrix& dy) { for (int idx = 0; idx < x.size(); ++idx) { - dy.setValue(idx, idy, 0.0); // For clarity, but unnecessary. The DenseMatrix - // constructor initializes all values to 0 if (idx == idy) dy.setValue(idx, idy, dsquare_ref_scalar(x[idx])); } From 2b3d79f0424006d66a8ba242927c680929a16d75 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Tue, 11 Feb 2025 13:53:10 -0500 Subject: [PATCH 43/52] Remove unneeded enzyme_autodiff declaration. --- examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp b/examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp index 4830521bb..ddab9834f 100644 --- a/examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp +++ b/examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp @@ -8,9 +8,6 @@ int enzyme_const; template return_type __enzyme_fwddiff(return_type*, int, T* ... ); -template -return_type __enzyme_autodiff(return_type*, int, T* ... ); - template return_type wrapper(T* obj) { obj->evalFunction(); From 37166f757a1870e5fe0dea7afde255546578ce3b Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Tue, 11 Feb 2025 13:53:49 -0500 Subject: [PATCH 44/52] EnzymeLibVectorCheck. --- examples/Enzyme/Library/CMakeLists.txt | 1 + examples/Enzyme/Library/Vector/CMakeLists.txt | 7 ++ .../Enzyme/Library/Vector/EnzymeVector.cpp | 75 +++++++++++++++++++ .../Enzyme/Library/Vector/EnzymeWrapper.hpp | 17 +++++ .../Enzyme/Library/Vector/VectorModel.cpp | 73 ++++++++++++++++++ .../Enzyme/Library/Vector/VectorModel.hpp | 23 ++++++ 6 files changed, 196 insertions(+) create mode 100644 examples/Enzyme/Library/Vector/CMakeLists.txt create mode 100644 examples/Enzyme/Library/Vector/EnzymeVector.cpp create mode 100644 examples/Enzyme/Library/Vector/EnzymeWrapper.hpp create mode 100644 examples/Enzyme/Library/Vector/VectorModel.cpp create mode 100644 examples/Enzyme/Library/Vector/VectorModel.hpp diff --git a/examples/Enzyme/Library/CMakeLists.txt b/examples/Enzyme/Library/CMakeLists.txt index d5a768c72..6dec74892 100644 --- a/examples/Enzyme/Library/CMakeLists.txt +++ b/examples/Enzyme/Library/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(Scalar) +add_subdirectory(Vector) diff --git a/examples/Enzyme/Library/Vector/CMakeLists.txt b/examples/Enzyme/Library/Vector/CMakeLists.txt new file mode 100644 index 000000000..eda952de8 --- /dev/null +++ b/examples/Enzyme/Library/Vector/CMakeLists.txt @@ -0,0 +1,7 @@ +enzyme_add_executable( + NAME EnzymeLibVectorCheck + SOURCES EnzymeVector.cpp VectorModel.cpp + LINK_LIBRARIES GRIDKIT::DenseMatrix +) + +add_test(NAME "EnzymeLibVectorCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymeLibVectorCheck) diff --git a/examples/Enzyme/Library/Vector/EnzymeVector.cpp b/examples/Enzyme/Library/Vector/EnzymeVector.cpp new file mode 100644 index 000000000..0f11215cd --- /dev/null +++ b/examples/Enzyme/Library/Vector/EnzymeVector.cpp @@ -0,0 +1,75 @@ +#include +#include +#include "VectorModel.hpp" + +inline +double dsquare_ref_scalar(double x) { + return 2.0 * x; +} + +DenseMatrix dsquare_ref(std::vector x, std::vector y) { + DenseMatrix jac(x.size(), y.size()); + for (int idy = 0; idy < y.size(); ++idy) + { + for (int idx = 0; idx < x.size(); ++idx) + { + if (idx == idy) + jac.setValue(idx, idy, dsquare_ref_scalar(x[idx])); + } + } + return jac; +} + +int main() { + // Size and variable declarations + constexpr int N = 10; + std::vector var(N); + + // Random input values + srand(time(NULL)); + for (int idx = 0; idx < var.size(); ++idx) + { + var[idx] = rand(); + } + + // Model + VectorModel* vector_model = new VectorModel(N); + vector_model->setVariable(var); + vector_model->evalResidual(); + vector_model->evalJacobian(); + std::vector& var_temp = vector_model->getVariable(); + std::vector& res = vector_model->getResidual(); + DenseMatrix& jac = vector_model->getJacobian(); + + // Reference Jacobian + DenseMatrix jac_ref = dsquare_ref(var, res); + + // Check + int fail = 0; + bool verbose = true; + for (int idy = 0; idy < res.size(); ++idy) + { + for (int idx = 0; idx < var.size(); ++idx) + { + if (std::abs(jac.getValue(idx, idy) - jac_ref.getValue(idx, idy)) > std::numeric_limits::epsilon()) + { + fail++; + if (verbose) + { + std::cout << "Result incorrect at line = " << idy << ", column = " << idx << "\n"; + std::cout << "x = " << var_temp[idx] << ", x^2 = " << res[idx] << ", d(x^2)/dx = " << jac.getValue(idx, idy) << "\n"; + } + } + } + } + if (verbose) + { + jac.printMatrix("Autodiff Jacobian"); + jac_ref.printMatrix("Reference Jacobian"); + } + std::cout << "Status: " << fail << "\n"; + return fail; + + // Cleanup + delete vector_model; +} diff --git a/examples/Enzyme/Library/Vector/EnzymeWrapper.hpp b/examples/Enzyme/Library/Vector/EnzymeWrapper.hpp new file mode 100644 index 000000000..fc9fe2c19 --- /dev/null +++ b/examples/Enzyme/Library/Vector/EnzymeWrapper.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include + +int enzyme_dup; +int enzyme_dupnoneed; +int enzyme_out; +int enzyme_const; + +template +std::vector __enzyme_fwddiff(std::vector*, int, T*, T*); + +template +std::vector wrapper(T* obj) { + obj->evalResidual(); + return obj->getResidual(); +} diff --git a/examples/Enzyme/Library/Vector/VectorModel.cpp b/examples/Enzyme/Library/Vector/VectorModel.cpp new file mode 100644 index 000000000..a580a6f0a --- /dev/null +++ b/examples/Enzyme/Library/Vector/VectorModel.cpp @@ -0,0 +1,73 @@ +#include "EnzymeWrapper.hpp" +#include "VectorModel.hpp" +#include + +VectorModel::VectorModel(int N) : + x_(N), + f_(N), + dfdx_(N, N) +{ +}; + +inline +double VectorModel::square_scalar(double x) { + return x * x; +} + +void VectorModel::square(std::vector& x, std::vector& y) { + for (int idx = 0; idx < x.size(); ++idx) + { + y[idx] = this->square_scalar(x[idx]); + } +} + +void VectorModel::setVariable(std::vector x) { + for (int idx = 0; idx < x.size(); ++idx) + { + x_[idx] = x[idx]; + } +} + +void VectorModel::evalResidual() { + square(x_, f_); +} + +void VectorModel::evalJacobian() { + const int N = x_.size(); + std::vector v(N); + VectorModel d_vector_model(N); + for (int idy = 0; idy < N; ++idy) + { + // Elementary vector for Jacobian-vector product + for (int idx = 0; idx < N; ++idx) + { + v[idx] = 0.0; + } + v[idy] = 1.0; + d_vector_model.setVariable(v); + + // Autodiff + std::vector d_res = __enzyme_fwddiff( + (std::vector*)wrapper, + enzyme_dup, this, &d_vector_model); + + // Store result + v = d_vector_model.getResidual(); + for (int idx = 0; idx < N; ++idx) + { + dfdx_.setValue(idx, idy, d_res[idx]); + } + } +} + +std::vector& VectorModel::getVariable() { + return x_; +} + +std::vector& VectorModel::getResidual() { + return f_; +} + +DenseMatrix& VectorModel::getJacobian() { + return dfdx_; +} diff --git a/examples/Enzyme/Library/Vector/VectorModel.hpp b/examples/Enzyme/Library/Vector/VectorModel.hpp new file mode 100644 index 000000000..7b754ab20 --- /dev/null +++ b/examples/Enzyme/Library/Vector/VectorModel.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +using DenseMatrix = GridKit::LinearAlgebra::DenseMatrix; + +class VectorModel { +private: + std::vector x_, f_; + DenseMatrix dfdx_; + inline double square_scalar(double); + void square(std::vector&, std::vector&); + +public: + VectorModel(int); + void setVariable(std::vector); + void evalResidual(); + void evalJacobian(); + std::vector& getVariable(); + std::vector& getResidual(); + DenseMatrix& getJacobian(); + ~VectorModel() {}; +}; From de8e4fcb94ac32a7f25a43819b956477039fa88f Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Tue, 11 Feb 2025 13:59:15 -0500 Subject: [PATCH 45/52] Minor fixes to EnzymeLibVectorCheck. --- examples/Enzyme/Library/Vector/EnzymeVector.cpp | 9 +++++---- examples/Enzyme/Library/Vector/VectorModel.cpp | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/Enzyme/Library/Vector/EnzymeVector.cpp b/examples/Enzyme/Library/Vector/EnzymeVector.cpp index 0f11215cd..70d3d5dd6 100644 --- a/examples/Enzyme/Library/Vector/EnzymeVector.cpp +++ b/examples/Enzyme/Library/Vector/EnzymeVector.cpp @@ -37,9 +37,9 @@ int main() { vector_model->setVariable(var); vector_model->evalResidual(); vector_model->evalJacobian(); - std::vector& var_temp = vector_model->getVariable(); - std::vector& res = vector_model->getResidual(); - DenseMatrix& jac = vector_model->getJacobian(); + std::vector var_temp = vector_model->getVariable(); + std::vector res = vector_model->getResidual(); + DenseMatrix jac = vector_model->getJacobian(); // Reference Jacobian DenseMatrix jac_ref = dsquare_ref(var, res); @@ -68,8 +68,9 @@ int main() { jac_ref.printMatrix("Reference Jacobian"); } std::cout << "Status: " << fail << "\n"; - return fail; // Cleanup delete vector_model; + + return fail; } diff --git a/examples/Enzyme/Library/Vector/VectorModel.cpp b/examples/Enzyme/Library/Vector/VectorModel.cpp index a580a6f0a..c664d6d5e 100644 --- a/examples/Enzyme/Library/Vector/VectorModel.cpp +++ b/examples/Enzyme/Library/Vector/VectorModel.cpp @@ -52,7 +52,6 @@ void VectorModel::evalJacobian() { enzyme_dup, this, &d_vector_model); // Store result - v = d_vector_model.getResidual(); for (int idx = 0; idx < N; ++idx) { dfdx_.setValue(idx, idy, d_res[idx]); From 471162001379a48bb175973029cbbbe012132326 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Tue, 11 Feb 2025 14:19:52 -0500 Subject: [PATCH 46/52] Correct way to specify library depencencies in enzyme_add_executable? --- cmake/FindEnzyme.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/FindEnzyme.cmake b/cmake/FindEnzyme.cmake index a7d998c5a..14420797e 100644 --- a/cmake/FindEnzyme.cmake +++ b/cmake/FindEnzyme.cmake @@ -166,7 +166,7 @@ macro(enzyme_add_executable) ) add_custom_command( - DEPENDS ${PHASE4} ${libsources} + DEPENDS ${PHASE4} ${enzyme_add_executable_LINK_LIBRARIES} OUTPUT ${PHASE5} COMMAND ${CMAKE_CXX_COMPILER} ${LINKER_FLAGS} ${PHASE4} -o ${PHASE5} ) From be030692e701938b2104d6d5603564bd67f0760b Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Thu, 13 Feb 2025 10:31:18 -0500 Subject: [PATCH 47/52] ModelLib -> GridKit on this branch. --- examples/Enzyme/PowerElectronics/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/Enzyme/PowerElectronics/main.cpp b/examples/Enzyme/PowerElectronics/main.cpp index 41d169e7b..d114a2d5b 100644 --- a/examples/Enzyme/PowerElectronics/main.cpp +++ b/examples/Enzyme/PowerElectronics/main.cpp @@ -6,8 +6,8 @@ using DenseMatrix = GridKit::LinearAlgebra::DenseMatrix; using SparseMatrix = COO_Matrix; -using DG = ModelLib::DistributedGenerator; -using DGParameters = ModelLib::DistributedGeneratorParameters; +using DG = GridKit::DistributedGenerator; +using DGParameters = GridKit::DistributedGeneratorParameters; int enzyme_dupnoneed; int enzyme_dup; From 8329bf906b3e0cdd357507a0435bbb261bbec63b Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Thu, 20 Feb 2025 09:47:23 -0500 Subject: [PATCH 48/52] Better documentation of the DenseMatrix class. --- src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp index bee75730d..839156f92 100644 --- a/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp +++ b/src/LinearAlgebra/DenseMatrix/DenseMatrix.hpp @@ -51,6 +51,9 @@ class DenseMatrix * * @tparam ScalarT * @tparam IdxT + * + * @param[in] IdxT - rows_size + * @param[in] IdxT - columns_size */ template DenseMatrix::DenseMatrix(const IdxT rows_size, const IdxT columns_size) : @@ -67,6 +70,10 @@ DenseMatrix::DenseMatrix(const IdxT rows_size, const IdxT columns * * @tparam ScalarT * @tparam IdxT + * + * @param[in] IdxT - i row index + * @param[in] IdxT - j column index + * @return ScalarT - value */ template inline ScalarT DenseMatrix::getValue(const IdxT i, const IdxT j) const @@ -81,6 +88,10 @@ inline ScalarT DenseMatrix::getValue(const IdxT i, const IdxT j) * * @tparam ScalarT * @tparam IdxT + * + * @param[in] IdxT - i row index + * @param[in] IdxT - j column index + * @param[in] ScalarT - value */ template inline void DenseMatrix::setValue(const IdxT i, const IdxT j, const ScalarT value) @@ -96,6 +107,8 @@ inline void DenseMatrix::setValue(const IdxT i, const IdxT j, con * * @tparam ScalarT * @tparam IdxT + * + * @param[in] COO_Matrix - values_COO */ template inline void DenseMatrix::setValues(COO_Matrix values_COO) @@ -113,6 +126,8 @@ inline void DenseMatrix::setValues(COO_Matrix valu * * @tparam ScalarT * @tparam IdxT + * + * @return Address of the vector containing matrix values */ template inline std::vector* DenseMatrix::getValues() @@ -125,6 +140,8 @@ inline std::vector* DenseMatrix::getValues() * * @tparam ScalarT * @tparam IdxT + * + * @return Address of the COO matrix containing the sparsified matrix values */ template inline COO_Matrix* DenseMatrix::getValuesCOO() @@ -176,6 +193,8 @@ inline void DenseMatrix::toCOO() * * @tparam ScalarT * @tparam IdxT + * + * @param[in] name to identify the specific matrix printed */ template inline void DenseMatrix::printMatrix(std::string name) From 140c2b785d14128a513f74ba337c8431fe26923f Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Fri, 21 Feb 2025 10:19:51 -0500 Subject: [PATCH 49/52] Rename a few variables in Enzyme examples. --- .../Enzyme/Library/Scalar/ScalarModel.cpp | 4 ++-- .../Enzyme/Library/Scalar/ScalarModel.hpp | 2 +- .../Enzyme/Library/Vector/EnzymeVector.cpp | 6 ++--- .../Enzyme/Library/Vector/VectorModel.cpp | 24 +++++++++---------- .../Enzyme/Library/Vector/VectorModel.hpp | 2 +- examples/Enzyme/PowerElectronics/main.cpp | 4 ++-- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/examples/Enzyme/Library/Scalar/ScalarModel.cpp b/examples/Enzyme/Library/Scalar/ScalarModel.cpp index 59651f493..c9aca32c0 100644 --- a/examples/Enzyme/Library/Scalar/ScalarModel.cpp +++ b/examples/Enzyme/Library/Scalar/ScalarModel.cpp @@ -18,7 +18,7 @@ void ScalarModel::evalFunction() { void ScalarModel::evalDerivative() { ScalarModel d_scalar_model; d_scalar_model.setVariable(1.0); - dfdx_ = __enzyme_fwddiff((double*)wrapper, enzyme_dup, this, &d_scalar_model); + df_dx_ = __enzyme_fwddiff((double*)wrapper, enzyme_dup, this, &d_scalar_model); } double ScalarModel::getVariable() const { @@ -30,5 +30,5 @@ double ScalarModel::getFunctionValue() const { } double ScalarModel::getDerivativeValue() const { - return dfdx_; + return df_dx_; } diff --git a/examples/Enzyme/Library/Scalar/ScalarModel.hpp b/examples/Enzyme/Library/Scalar/ScalarModel.hpp index 6b29e4872..81ca9e538 100644 --- a/examples/Enzyme/Library/Scalar/ScalarModel.hpp +++ b/examples/Enzyme/Library/Scalar/ScalarModel.hpp @@ -2,7 +2,7 @@ class ScalarModel { private: - double x_, f_, dfdx_; + double x_, f_, df_dx_; inline double square(double); public: diff --git a/examples/Enzyme/Library/Vector/EnzymeVector.cpp b/examples/Enzyme/Library/Vector/EnzymeVector.cpp index 70d3d5dd6..401722cba 100644 --- a/examples/Enzyme/Library/Vector/EnzymeVector.cpp +++ b/examples/Enzyme/Library/Vector/EnzymeVector.cpp @@ -22,8 +22,8 @@ DenseMatrix dsquare_ref(std::vector x, std::vector y) { int main() { // Size and variable declarations - constexpr int N = 10; - std::vector var(N); + constexpr int n = 10; + std::vector var(n); // Random input values srand(time(NULL)); @@ -33,7 +33,7 @@ int main() { } // Model - VectorModel* vector_model = new VectorModel(N); + VectorModel* vector_model = new VectorModel(n); vector_model->setVariable(var); vector_model->evalResidual(); vector_model->evalJacobian(); diff --git a/examples/Enzyme/Library/Vector/VectorModel.cpp b/examples/Enzyme/Library/Vector/VectorModel.cpp index c664d6d5e..dd27aff82 100644 --- a/examples/Enzyme/Library/Vector/VectorModel.cpp +++ b/examples/Enzyme/Library/Vector/VectorModel.cpp @@ -2,10 +2,10 @@ #include "VectorModel.hpp" #include -VectorModel::VectorModel(int N) : - x_(N), - f_(N), - dfdx_(N, N) +VectorModel::VectorModel(int n) : + x_(n), + f_(n), + df_dx_(n, n) { }; @@ -33,13 +33,13 @@ void VectorModel::evalResidual() { } void VectorModel::evalJacobian() { - const int N = x_.size(); - std::vector v(N); - VectorModel d_vector_model(N); - for (int idy = 0; idy < N; ++idy) + const int n = x_.size(); + std::vector v(n); + VectorModel d_vector_model(n); + for (int idy = 0; idy < n; ++idy) { // Elementary vector for Jacobian-vector product - for (int idx = 0; idx < N; ++idx) + for (int idx = 0; idx < n; ++idx) { v[idx] = 0.0; } @@ -52,9 +52,9 @@ void VectorModel::evalJacobian() { enzyme_dup, this, &d_vector_model); // Store result - for (int idx = 0; idx < N; ++idx) + for (int idx = 0; idx < n; ++idx) { - dfdx_.setValue(idx, idy, d_res[idx]); + df_dx_.setValue(idx, idy, d_res[idx]); } } } @@ -68,5 +68,5 @@ std::vector& VectorModel::getResidual() { } DenseMatrix& VectorModel::getJacobian() { - return dfdx_; + return df_dx_; } diff --git a/examples/Enzyme/Library/Vector/VectorModel.hpp b/examples/Enzyme/Library/Vector/VectorModel.hpp index 7b754ab20..8dcf2819e 100644 --- a/examples/Enzyme/Library/Vector/VectorModel.hpp +++ b/examples/Enzyme/Library/Vector/VectorModel.hpp @@ -7,7 +7,7 @@ using DenseMatrix = GridKit::LinearAlgebra::DenseMatrix; class VectorModel { private: std::vector x_, f_; - DenseMatrix dfdx_; + DenseMatrix df_dx_; inline double square_scalar(double); void square(std::vector&, std::vector&); diff --git a/examples/Enzyme/PowerElectronics/main.cpp b/examples/Enzyme/PowerElectronics/main.cpp index d114a2d5b..a5e4be86d 100644 --- a/examples/Enzyme/PowerElectronics/main.cpp +++ b/examples/Enzyme/PowerElectronics/main.cpp @@ -35,12 +35,12 @@ void evaluateResidual(std::vector y_, std::vector f_) constexpr double rLc_ = 0.03; constexpr double Lc_ = 0.35e-3; - constexpr bool refframe_ = true; + constexpr bool ref_frame_ = true; std::vector yp_(0); double omega = wb_ - mp_ * y_[4]; - if (refframe_) + if (ref_frame_) { f_[0] = omega - y_[0]; } From 356d8a5c2f0746c44d22c443ae833233d2c606a6 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Mon, 24 Feb 2025 15:05:50 -0500 Subject: [PATCH 50/52] powerelec --> power_elec in GRIDKIT::targets. --- examples/DistributedGeneratorTest/CMakeLists.txt | 6 +++--- examples/Enzyme/PowerElectronics/CMakeLists.txt | 2 +- examples/Microgrid/CMakeLists.txt | 8 ++++---- examples/RLCircuit/CMakeLists.txt | 8 ++++---- examples/ScaleMicrogrid/CMakeLists.txt | 8 ++++---- src/Model/PowerElectronics/Capacitor/CMakeLists.txt | 4 ++-- .../PowerElectronics/DistributedGenerator/CMakeLists.txt | 4 ++-- src/Model/PowerElectronics/InductionMotor/CMakeLists.txt | 4 ++-- src/Model/PowerElectronics/Inductor/CMakeLists.txt | 4 ++-- .../PowerElectronics/LinearTransformer/CMakeLists.txt | 4 ++-- src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt | 4 ++-- src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt | 4 ++-- src/Model/PowerElectronics/MicrogridLoad/CMakeLists.txt | 4 ++-- src/Model/PowerElectronics/Resistor/CMakeLists.txt | 4 ++-- .../PowerElectronics/SynchronousMachine/CMakeLists.txt | 4 ++-- .../PowerElectronics/TransmissionLine/CMakeLists.txt | 4 ++-- src/Model/PowerElectronics/VoltageSource/CMakeLists.txt | 4 ++-- 17 files changed, 40 insertions(+), 40 deletions(-) diff --git a/examples/DistributedGeneratorTest/CMakeLists.txt b/examples/DistributedGeneratorTest/CMakeLists.txt index 4a2616112..6ed544e93 100644 --- a/examples/DistributedGeneratorTest/CMakeLists.txt +++ b/examples/DistributedGeneratorTest/CMakeLists.txt @@ -3,9 +3,9 @@ add_executable(dgtest DGTest.cpp) -target_link_libraries(dgtest GRIDKIT::powerelec_disgen - GRIDKIT::powerelec_microline - GRIDKIT::powerelec_microload +target_link_libraries(dgtest GRIDKIT::power_elec_disgen + GRIDKIT::power_elec_microline + GRIDKIT::power_elec_microload GRIDKIT::solvers_dyn) add_test(NAME DistributedGeneratorTest COMMAND $) diff --git a/examples/Enzyme/PowerElectronics/CMakeLists.txt b/examples/Enzyme/PowerElectronics/CMakeLists.txt index 59c5eb445..a8e74e881 100644 --- a/examples/Enzyme/PowerElectronics/CMakeLists.txt +++ b/examples/Enzyme/PowerElectronics/CMakeLists.txt @@ -1,7 +1,7 @@ enzyme_add_executable( NAME EnzymePowerElectronicsCheck SOURCES main.cpp - LINK_LIBRARIES GRIDKIT::DenseMatrix GRIDKIT::powerelec_disgen + LINK_LIBRARIES GRIDKIT::DenseMatrix GRIDKIT::power_elec_disgen ) add_test(NAME "EnzymePowerElectronicsCheck" COMMAND ${CMAKE_CURRENT_BINARY_DIR}/EnzymePowerElectronicsCheck) diff --git a/examples/Microgrid/CMakeLists.txt b/examples/Microgrid/CMakeLists.txt index b5f5d584a..9d627fcac 100644 --- a/examples/Microgrid/CMakeLists.txt +++ b/examples/Microgrid/CMakeLists.txt @@ -3,11 +3,11 @@ add_executable(microgrid Microgrid.cpp) -target_link_libraries(microgrid GRIDKIT::powerelec_disgen - GRIDKIT::powerelec_microline - GRIDKIT::powerelec_microload +target_link_libraries(microgrid GRIDKIT::power_elec_disgen + GRIDKIT::power_elec_microline + GRIDKIT::power_elec_microload GRIDKIT::solvers_dyn - GRIDKIT::powerelec_microbusdq) + GRIDKIT::power_elec_microbusdq) add_test(NAME Microgrid COMMAND $) install(TARGETS microgrid RUNTIME DESTINATION bin) diff --git a/examples/RLCircuit/CMakeLists.txt b/examples/RLCircuit/CMakeLists.txt index e7e052603..56599c521 100644 --- a/examples/RLCircuit/CMakeLists.txt +++ b/examples/RLCircuit/CMakeLists.txt @@ -3,10 +3,10 @@ add_executable(rlcircuit RLCircuit.cpp) -target_link_libraries(rlcircuit GRIDKIT::powerelec_capacitor - GRIDKIT::powerelec_inductor - GRIDKIT::powerelec_resistor - GRIDKIT::powerelec_voltagesource +target_link_libraries(rlcircuit GRIDKIT::power_elec_capacitor + GRIDKIT::power_elec_inductor + GRIDKIT::power_elec_resistor + GRIDKIT::power_elec_voltagesource GRIDKIT::solvers_dyn) add_test(NAME RLCircuit COMMAND $) diff --git a/examples/ScaleMicrogrid/CMakeLists.txt b/examples/ScaleMicrogrid/CMakeLists.txt index bbd3890d6..1f0fe0cbb 100644 --- a/examples/ScaleMicrogrid/CMakeLists.txt +++ b/examples/ScaleMicrogrid/CMakeLists.txt @@ -3,11 +3,11 @@ add_executable(scalemicrogrid ScaleMicrogrid.cpp) -target_link_libraries(scalemicrogrid GRIDKIT::powerelec_disgen - GRIDKIT::powerelec_microline - GRIDKIT::powerelec_microload +target_link_libraries(scalemicrogrid GRIDKIT::power_elec_disgen + GRIDKIT::power_elec_microline + GRIDKIT::power_elec_microload GRIDKIT::solvers_dyn - GRIDKIT::powerelec_microbusdq) + GRIDKIT::power_elec_microbusdq) add_test(NAME ScaleMicrogrid COMMAND $) install(TARGETS scalemicrogrid RUNTIME DESTINATION bin) diff --git a/src/Model/PowerElectronics/Capacitor/CMakeLists.txt b/src/Model/PowerElectronics/Capacitor/CMakeLists.txt index 62efc1795..2e05fad26 100644 --- a/src/Model/PowerElectronics/Capacitor/CMakeLists.txt +++ b/src/Model/PowerElectronics/Capacitor/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_capacitor +gridkit_add_library(power_elec_capacitor SOURCES Capacitor.cpp OUTPUT_NAME - gridkit_powerelec_capacitor) \ No newline at end of file + gridkit_power_elec_capacitor) \ No newline at end of file diff --git a/src/Model/PowerElectronics/DistributedGenerator/CMakeLists.txt b/src/Model/PowerElectronics/DistributedGenerator/CMakeLists.txt index 22652f53b..3d4b805cb 100644 --- a/src/Model/PowerElectronics/DistributedGenerator/CMakeLists.txt +++ b/src/Model/PowerElectronics/DistributedGenerator/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_disgen +gridkit_add_library(power_elec_disgen SOURCES DistributedGenerator.cpp OUTPUT_NAME - gridkit_powerelec_disgen) \ No newline at end of file + gridkit_power_elec_disgen) \ No newline at end of file diff --git a/src/Model/PowerElectronics/InductionMotor/CMakeLists.txt b/src/Model/PowerElectronics/InductionMotor/CMakeLists.txt index 95ef42436..ce94553a9 100644 --- a/src/Model/PowerElectronics/InductionMotor/CMakeLists.txt +++ b/src/Model/PowerElectronics/InductionMotor/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_inductionmotor +gridkit_add_library(power_elec_inductionmotor SOURCES InductionMotor.cpp OUTPUT_NAME - gridkit_powerelec_inductionmotor) \ No newline at end of file + gridkit_power_elec_inductionmotor) \ No newline at end of file diff --git a/src/Model/PowerElectronics/Inductor/CMakeLists.txt b/src/Model/PowerElectronics/Inductor/CMakeLists.txt index 4c620030f..3570a451f 100644 --- a/src/Model/PowerElectronics/Inductor/CMakeLists.txt +++ b/src/Model/PowerElectronics/Inductor/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_inductor +gridkit_add_library(power_elec_inductor SOURCES Inductor.cpp OUTPUT_NAME - gridkit_powerelec_inductor) \ No newline at end of file + gridkit_power_elec_inductor) \ No newline at end of file diff --git a/src/Model/PowerElectronics/LinearTransformer/CMakeLists.txt b/src/Model/PowerElectronics/LinearTransformer/CMakeLists.txt index eaf95c043..da1e7efba 100644 --- a/src/Model/PowerElectronics/LinearTransformer/CMakeLists.txt +++ b/src/Model/PowerElectronics/LinearTransformer/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_lineartrasnformer +gridkit_add_library(power_elec_lineartrasnformer SOURCES LinearTransformer.cpp OUTPUT_NAME - gridkit_powerelec_lineartrasnformer) \ No newline at end of file + gridkit_power_elec_lineartrasnformer) \ No newline at end of file diff --git a/src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt b/src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt index 1006170f4..21efbb7d4 100644 --- a/src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt +++ b/src/Model/PowerElectronics/MicrogridBusDQ/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_microbusdq +gridkit_add_library(power_elec_microbusdq SOURCES MicrogridBusDQ.cpp OUTPUT_NAME - gridkit_powerelec_microbusdq) \ No newline at end of file + gridkit_power_elec_microbusdq) \ No newline at end of file diff --git a/src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt b/src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt index 1f0ad6f10..3f4224600 100644 --- a/src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt +++ b/src/Model/PowerElectronics/MicrogridLine/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_microline +gridkit_add_library(power_elec_microline SOURCES MicrogridLine.cpp OUTPUT_NAME - gridkit_powerelec_microline) \ No newline at end of file + gridkit_power_elec_microline) \ No newline at end of file diff --git a/src/Model/PowerElectronics/MicrogridLoad/CMakeLists.txt b/src/Model/PowerElectronics/MicrogridLoad/CMakeLists.txt index 313d47688..7f9eaf671 100644 --- a/src/Model/PowerElectronics/MicrogridLoad/CMakeLists.txt +++ b/src/Model/PowerElectronics/MicrogridLoad/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_microload +gridkit_add_library(power_elec_microload SOURCES MicrogridLoad.cpp OUTPUT_NAME - gridkit_powerelec_microload) \ No newline at end of file + gridkit_power_elec_microload) \ No newline at end of file diff --git a/src/Model/PowerElectronics/Resistor/CMakeLists.txt b/src/Model/PowerElectronics/Resistor/CMakeLists.txt index 9386bda83..757597a6a 100644 --- a/src/Model/PowerElectronics/Resistor/CMakeLists.txt +++ b/src/Model/PowerElectronics/Resistor/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_resistor +gridkit_add_library(power_elec_resistor SOURCES Resistor.cpp OUTPUT_NAME - gridkit_powerelec_resistor) \ No newline at end of file + gridkit_power_elec_resistor) \ No newline at end of file diff --git a/src/Model/PowerElectronics/SynchronousMachine/CMakeLists.txt b/src/Model/PowerElectronics/SynchronousMachine/CMakeLists.txt index bfaeace4b..c42816d96 100644 --- a/src/Model/PowerElectronics/SynchronousMachine/CMakeLists.txt +++ b/src/Model/PowerElectronics/SynchronousMachine/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_synmachine +gridkit_add_library(power_elec_synmachine SOURCES SynchronousMachine.cpp OUTPUT_NAME - gridkit_powerelec_synmachine) \ No newline at end of file + gridkit_power_elec_synmachine) \ No newline at end of file diff --git a/src/Model/PowerElectronics/TransmissionLine/CMakeLists.txt b/src/Model/PowerElectronics/TransmissionLine/CMakeLists.txt index 6e2cea4f4..c80b3b6de 100644 --- a/src/Model/PowerElectronics/TransmissionLine/CMakeLists.txt +++ b/src/Model/PowerElectronics/TransmissionLine/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_tranline +gridkit_add_library(power_elec_tranline SOURCES TransmissionLine.cpp OUTPUT_NAME - gridkit_powerelec_tranline) \ No newline at end of file + gridkit_power_elec_tranline) \ No newline at end of file diff --git a/src/Model/PowerElectronics/VoltageSource/CMakeLists.txt b/src/Model/PowerElectronics/VoltageSource/CMakeLists.txt index 7196f4d43..4fc504742 100644 --- a/src/Model/PowerElectronics/VoltageSource/CMakeLists.txt +++ b/src/Model/PowerElectronics/VoltageSource/CMakeLists.txt @@ -1,8 +1,8 @@ -gridkit_add_library(powerelec_voltagesource +gridkit_add_library(power_elec_voltagesource SOURCES VoltageSource.cpp OUTPUT_NAME - gridkit_powerelec_voltagesource) \ No newline at end of file + gridkit_power_elec_voltagesource) \ No newline at end of file From 495ab8c1f7f0865fd911f25d2e9bc1d819273223 Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Wed, 26 Feb 2025 14:42:37 -0500 Subject: [PATCH 51/52] Added comments to describe the Enzyme examples along with TODO items for a follow-up PR. --- examples/Enzyme/Library/Scalar/EnzymeScalar.cpp | 8 ++++++++ examples/Enzyme/Library/Scalar/ScalarModel.hpp | 4 ++++ examples/Enzyme/Library/Vector/EnzymeVector.cpp | 9 +++++++++ examples/Enzyme/Library/Vector/VectorModel.hpp | 4 ++++ examples/Enzyme/PowerElectronics/main.cpp | 12 +++++++++++- examples/Enzyme/Standalone/EnzymeScalar.cpp | 7 +++++++ examples/Enzyme/Standalone/EnzymeVector.cpp | 10 ++++++++++ 7 files changed, 53 insertions(+), 1 deletion(-) diff --git a/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp b/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp index eaa3bcd5c..459df86b4 100644 --- a/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp +++ b/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp @@ -2,6 +2,14 @@ #include #include "ScalarModel.hpp" +/** + * @brief Example that computes the derivative of a library function + * (implemented as the member function of a class and operating directly on class members) + * by automatic differentiation via Enzyme. + * + * TODO: Convert this into a unit test. + */ + int main() { int fail = 0; ScalarModel scalar_model; diff --git a/examples/Enzyme/Library/Scalar/ScalarModel.hpp b/examples/Enzyme/Library/Scalar/ScalarModel.hpp index 81ca9e538..c6505103b 100644 --- a/examples/Enzyme/Library/Scalar/ScalarModel.hpp +++ b/examples/Enzyme/Library/Scalar/ScalarModel.hpp @@ -1,5 +1,9 @@ #pragma once +/** + * @brief Class providing methods to evaluate a function and its derivative. + * This is used to test automatic differentiation. + */ class ScalarModel { private: double x_, f_, df_dx_; diff --git a/examples/Enzyme/Library/Vector/EnzymeVector.cpp b/examples/Enzyme/Library/Vector/EnzymeVector.cpp index 401722cba..e00ed6e5e 100644 --- a/examples/Enzyme/Library/Vector/EnzymeVector.cpp +++ b/examples/Enzyme/Library/Vector/EnzymeVector.cpp @@ -2,11 +2,20 @@ #include #include "VectorModel.hpp" +/** + * @brief Example that computes the Jacobian of a vector-valued residual + * (implemented as the member function of a class and operating directly on class members) + * by automatic differentiation via Enzyme. + * + * TODO: Convert this into a unit test. + */ + inline double dsquare_ref_scalar(double x) { return 2.0 * x; } +// Reference Jacobian DenseMatrix dsquare_ref(std::vector x, std::vector y) { DenseMatrix jac(x.size(), y.size()); for (int idy = 0; idy < y.size(); ++idy) diff --git a/examples/Enzyme/Library/Vector/VectorModel.hpp b/examples/Enzyme/Library/Vector/VectorModel.hpp index 8dcf2819e..d0ad04033 100644 --- a/examples/Enzyme/Library/Vector/VectorModel.hpp +++ b/examples/Enzyme/Library/Vector/VectorModel.hpp @@ -4,6 +4,10 @@ using DenseMatrix = GridKit::LinearAlgebra::DenseMatrix; +/** + * @brief Class providing methods to evaluate a vector-valued residual and its Jacobian. + * This is used to test automatic differentiation. + */ class VectorModel { private: std::vector x_, f_; diff --git a/examples/Enzyme/PowerElectronics/main.cpp b/examples/Enzyme/PowerElectronics/main.cpp index a5e4be86d..c53296e97 100644 --- a/examples/Enzyme/PowerElectronics/main.cpp +++ b/examples/Enzyme/PowerElectronics/main.cpp @@ -4,6 +4,15 @@ #include #include +/** + * @brief Standalone example that computes the Jacobian associated with the + * residual function of DistributedGenerator. We compare the Jacobian obtained + * by automatic differentiation via Enzyme to the analytical Jacobian + * implemented witin GridKit. + * + * TODO: Move automatic differentiation inside GridKit and convert this into a unit test. + */ + using DenseMatrix = GridKit::LinearAlgebra::DenseMatrix; using SparseMatrix = COO_Matrix; using DG = GridKit::DistributedGenerator; @@ -84,6 +93,7 @@ void evaluateResidual(std::vector y_, std::vector f_) f_[15] = -yp_[15] - (rLc_ / Lc_) * y_[15] - omega * y_[14] + (y_[13] - vbq_in) / Lc_; } +// Function that computes the Jacobian via automatic differentiation template void EnzymeModelJacobian(T* model, DenseMatrix& jac) { int N = model->size(); @@ -178,6 +188,6 @@ int main() { // Cleanup delete dg; - return fail; + return fail; } diff --git a/examples/Enzyme/Standalone/EnzymeScalar.cpp b/examples/Enzyme/Standalone/EnzymeScalar.cpp index 2c4da8c7a..80ebb2b0f 100644 --- a/examples/Enzyme/Standalone/EnzymeScalar.cpp +++ b/examples/Enzyme/Standalone/EnzymeScalar.cpp @@ -1,6 +1,13 @@ #include #include +/** + * @brief Standalone example that computes the derivative of a scalar function + * by automatic differentiation via Enzyme. + * + * TODO: Convert this into a unit test. + */ + double square(double x) { return x * x; } diff --git a/examples/Enzyme/Standalone/EnzymeVector.cpp b/examples/Enzyme/Standalone/EnzymeVector.cpp index 87df1d9c7..868e5ef74 100644 --- a/examples/Enzyme/Standalone/EnzymeVector.cpp +++ b/examples/Enzyme/Standalone/EnzymeVector.cpp @@ -3,6 +3,13 @@ #include #include +/** + * @brief Standalone example that computes the Jacobian of a vector-valued function + * by automatic differentiation via Enzyme. + * + * TODO: Convert this into a unit test. + */ + using DenseMatrix = GridKit::LinearAlgebra::DenseMatrix; int enzyme_dupnoneed; int enzyme_dup; @@ -20,6 +27,7 @@ double dsquare_ref_scalar(double x) { return 2.0 * x; } +// Vector-valued function to differentiate void square(std::vector x, std::vector& y) { for (int idx = 0; idx < x.size(); ++idx) { @@ -27,6 +35,7 @@ void square(std::vector x, std::vector& y) { } } +// Reference Jacobian void dsquare_ref(std::vector x, std::vector y, DenseMatrix& dy) { for (int idy = 0; idy < y.size(); ++idy) { @@ -38,6 +47,7 @@ void dsquare_ref(std::vector x, std::vector y, DenseMatrix& dy) } } +// Function that computes the Jacobian via automatic differentiation void dsquare(std::vector x, std::vector y, DenseMatrix& dy) { std::vector v(x.size()); std::vector d_y(y.size()); From 4fc7f463acab8db7b748148e4ad304271988bf6b Mon Sep 17 00:00:00 2001 From: Nicholson Koukpaizan Date: Thu, 27 Feb 2025 10:17:38 -0500 Subject: [PATCH 52/52] Fix braces in Enzyme examples. --- .../Enzyme/Library/Scalar/EnzymeScalar.cpp | 3 +- .../Enzyme/Library/Scalar/EnzymeWrapper.hpp | 3 +- .../Enzyme/Library/Scalar/ScalarModel.cpp | 29 +++++++++++++----- .../Enzyme/Library/Scalar/ScalarModel.hpp | 7 +++-- .../Enzyme/Library/Vector/EnzymeVector.cpp | 9 ++++-- .../Enzyme/Library/Vector/EnzymeWrapper.hpp | 3 +- .../Enzyme/Library/Vector/VectorModel.cpp | 30 +++++++++++++------ .../Enzyme/Library/Vector/VectorModel.hpp | 5 ++-- examples/Enzyme/PowerElectronics/main.cpp | 6 ++-- examples/Enzyme/Standalone/EnzymeScalar.cpp | 6 ++-- examples/Enzyme/Standalone/EnzymeVector.cpp | 15 ++++++---- 11 files changed, 80 insertions(+), 36 deletions(-) diff --git a/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp b/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp index 459df86b4..abc1a9d07 100644 --- a/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp +++ b/examples/Enzyme/Library/Scalar/EnzymeScalar.cpp @@ -10,7 +10,8 @@ * TODO: Convert this into a unit test. */ -int main() { +int main() +{ int fail = 0; ScalarModel scalar_model; double var = 5.0; diff --git a/examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp b/examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp index ddab9834f..8e659dea4 100644 --- a/examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp +++ b/examples/Enzyme/Library/Scalar/EnzymeWrapper.hpp @@ -9,7 +9,8 @@ template return_type __enzyme_fwddiff(return_type*, int, T* ... ); template -return_type wrapper(T* obj) { +return_type wrapper(T* obj) +{ obj->evalFunction(); return obj->getFunctionValue(); } diff --git a/examples/Enzyme/Library/Scalar/ScalarModel.cpp b/examples/Enzyme/Library/Scalar/ScalarModel.cpp index c9aca32c0..06fb9c1b6 100644 --- a/examples/Enzyme/Library/Scalar/ScalarModel.cpp +++ b/examples/Enzyme/Library/Scalar/ScalarModel.cpp @@ -2,33 +2,48 @@ #include "ScalarModel.hpp" #include +ScalarModel::ScalarModel() +{ +} + inline -double ScalarModel::square(double x) { +double ScalarModel::square(double x) +{ return x * x; } -void ScalarModel::setVariable(double x) { +void ScalarModel::setVariable(double x) +{ x_ = x; } -void ScalarModel::evalFunction() { +void ScalarModel::evalFunction() +{ f_ = square(x_); } -void ScalarModel::evalDerivative() { +void ScalarModel::evalDerivative() +{ ScalarModel d_scalar_model; d_scalar_model.setVariable(1.0); df_dx_ = __enzyme_fwddiff((double*)wrapper, enzyme_dup, this, &d_scalar_model); } -double ScalarModel::getVariable() const { +double ScalarModel::getVariable() const +{ return x_; } -double ScalarModel::getFunctionValue() const { +double ScalarModel::getFunctionValue() const +{ return f_; } -double ScalarModel::getDerivativeValue() const { +double ScalarModel::getDerivativeValue() const +{ return df_dx_; } + +ScalarModel::~ScalarModel() +{ +} diff --git a/examples/Enzyme/Library/Scalar/ScalarModel.hpp b/examples/Enzyme/Library/Scalar/ScalarModel.hpp index c6505103b..2632bf59d 100644 --- a/examples/Enzyme/Library/Scalar/ScalarModel.hpp +++ b/examples/Enzyme/Library/Scalar/ScalarModel.hpp @@ -4,18 +4,19 @@ * @brief Class providing methods to evaluate a function and its derivative. * This is used to test automatic differentiation. */ -class ScalarModel { +class ScalarModel +{ private: double x_, f_, df_dx_; inline double square(double); public: - ScalarModel() {}; + ScalarModel(); void setVariable(double); void evalFunction(); void evalDerivative(); double getVariable() const; double getFunctionValue() const; double getDerivativeValue() const; - ~ScalarModel() {}; + ~ScalarModel(); }; diff --git a/examples/Enzyme/Library/Vector/EnzymeVector.cpp b/examples/Enzyme/Library/Vector/EnzymeVector.cpp index e00ed6e5e..f18ef3e2a 100644 --- a/examples/Enzyme/Library/Vector/EnzymeVector.cpp +++ b/examples/Enzyme/Library/Vector/EnzymeVector.cpp @@ -11,12 +11,14 @@ */ inline -double dsquare_ref_scalar(double x) { +double dsquare_ref_scalar(double x) +{ return 2.0 * x; } // Reference Jacobian -DenseMatrix dsquare_ref(std::vector x, std::vector y) { +DenseMatrix dsquare_ref(std::vector x, std::vector y) +{ DenseMatrix jac(x.size(), y.size()); for (int idy = 0; idy < y.size(); ++idy) { @@ -29,7 +31,8 @@ DenseMatrix dsquare_ref(std::vector x, std::vector y) { return jac; } -int main() { +int main() +{ // Size and variable declarations constexpr int n = 10; std::vector var(n); diff --git a/examples/Enzyme/Library/Vector/EnzymeWrapper.hpp b/examples/Enzyme/Library/Vector/EnzymeWrapper.hpp index fc9fe2c19..3306ab957 100644 --- a/examples/Enzyme/Library/Vector/EnzymeWrapper.hpp +++ b/examples/Enzyme/Library/Vector/EnzymeWrapper.hpp @@ -11,7 +11,8 @@ template std::vector __enzyme_fwddiff(std::vector*, int, T*, T*); template -std::vector wrapper(T* obj) { +std::vector wrapper(T* obj) +{ obj->evalResidual(); return obj->getResidual(); } diff --git a/examples/Enzyme/Library/Vector/VectorModel.cpp b/examples/Enzyme/Library/Vector/VectorModel.cpp index dd27aff82..33f312ccd 100644 --- a/examples/Enzyme/Library/Vector/VectorModel.cpp +++ b/examples/Enzyme/Library/Vector/VectorModel.cpp @@ -7,32 +7,37 @@ VectorModel::VectorModel(int n) : f_(n), df_dx_(n, n) { -}; +} inline -double VectorModel::square_scalar(double x) { +double VectorModel::square_scalar(double x) +{ return x * x; } -void VectorModel::square(std::vector& x, std::vector& y) { +void VectorModel::square(std::vector& x, std::vector& y) +{ for (int idx = 0; idx < x.size(); ++idx) { y[idx] = this->square_scalar(x[idx]); } } -void VectorModel::setVariable(std::vector x) { +void VectorModel::setVariable(std::vector x) +{ for (int idx = 0; idx < x.size(); ++idx) { x_[idx] = x[idx]; } } -void VectorModel::evalResidual() { +void VectorModel::evalResidual() +{ square(x_, f_); } -void VectorModel::evalJacobian() { +void VectorModel::evalJacobian() +{ const int n = x_.size(); std::vector v(n); VectorModel d_vector_model(n); @@ -59,14 +64,21 @@ void VectorModel::evalJacobian() { } } -std::vector& VectorModel::getVariable() { +std::vector& VectorModel::getVariable() +{ return x_; } -std::vector& VectorModel::getResidual() { +std::vector& VectorModel::getResidual() +{ return f_; } -DenseMatrix& VectorModel::getJacobian() { +DenseMatrix& VectorModel::getJacobian() +{ return df_dx_; } + +VectorModel::~VectorModel() +{ +} diff --git a/examples/Enzyme/Library/Vector/VectorModel.hpp b/examples/Enzyme/Library/Vector/VectorModel.hpp index d0ad04033..5ff5d87eb 100644 --- a/examples/Enzyme/Library/Vector/VectorModel.hpp +++ b/examples/Enzyme/Library/Vector/VectorModel.hpp @@ -8,7 +8,8 @@ using DenseMatrix = GridKit::LinearAlgebra::DenseMatrix; * @brief Class providing methods to evaluate a vector-valued residual and its Jacobian. * This is used to test automatic differentiation. */ -class VectorModel { +class VectorModel +{ private: std::vector x_, f_; DenseMatrix df_dx_; @@ -23,5 +24,5 @@ class VectorModel { std::vector& getVariable(); std::vector& getResidual(); DenseMatrix& getJacobian(); - ~VectorModel() {}; + ~VectorModel(); }; diff --git a/examples/Enzyme/PowerElectronics/main.cpp b/examples/Enzyme/PowerElectronics/main.cpp index c53296e97..b15b62e5a 100644 --- a/examples/Enzyme/PowerElectronics/main.cpp +++ b/examples/Enzyme/PowerElectronics/main.cpp @@ -95,7 +95,8 @@ void evaluateResidual(std::vector y_, std::vector f_) // Function that computes the Jacobian via automatic differentiation template -void EnzymeModelJacobian(T* model, DenseMatrix& jac) { +void EnzymeModelJacobian(T* model, DenseMatrix& jac) +{ int N = model->size(); std::vector y(N); std::vector v(N); @@ -125,7 +126,8 @@ void EnzymeModelJacobian(T* model, DenseMatrix& jac) { } } -int main() { +int main() +{ // Model DGParameters parms; parms.wb_ = 2.0*M_PI*50.0; diff --git a/examples/Enzyme/Standalone/EnzymeScalar.cpp b/examples/Enzyme/Standalone/EnzymeScalar.cpp index 80ebb2b0f..99333b1a8 100644 --- a/examples/Enzyme/Standalone/EnzymeScalar.cpp +++ b/examples/Enzyme/Standalone/EnzymeScalar.cpp @@ -8,12 +8,14 @@ * TODO: Convert this into a unit test. */ -double square(double x) { +double square(double x) +{ return x * x; } double __enzyme_autodiff(double(*)(double), ...); -double dsquare(double x) { +double dsquare(double x) +{ return __enzyme_autodiff(square, x); } diff --git a/examples/Enzyme/Standalone/EnzymeVector.cpp b/examples/Enzyme/Standalone/EnzymeVector.cpp index 868e5ef74..ef6d60c16 100644 --- a/examples/Enzyme/Standalone/EnzymeVector.cpp +++ b/examples/Enzyme/Standalone/EnzymeVector.cpp @@ -18,17 +18,20 @@ void __enzyme_fwddiff(void*, int, std::vector, std::vector, int, std::vector, std::vector*); inline -double square_scalar(double x) { +double square_scalar(double x) +{ return x * x; } inline -double dsquare_ref_scalar(double x) { +double dsquare_ref_scalar(double x) +{ return 2.0 * x; } // Vector-valued function to differentiate -void square(std::vector x, std::vector& y) { +void square(std::vector x, std::vector& y) +{ for (int idx = 0; idx < x.size(); ++idx) { y[idx] = square_scalar(x[idx]); @@ -36,7 +39,8 @@ void square(std::vector x, std::vector& y) { } // Reference Jacobian -void dsquare_ref(std::vector x, std::vector y, DenseMatrix& dy) { +void dsquare_ref(std::vector x, std::vector y, DenseMatrix& dy) +{ for (int idy = 0; idy < y.size(); ++idy) { for (int idx = 0; idx < x.size(); ++idx) @@ -48,7 +52,8 @@ void dsquare_ref(std::vector x, std::vector y, DenseMatrix& dy) } // Function that computes the Jacobian via automatic differentiation -void dsquare(std::vector x, std::vector y, DenseMatrix& dy) { +void dsquare(std::vector x, std::vector y, DenseMatrix& dy) +{ std::vector v(x.size()); std::vector d_y(y.size()); for (int idy = 0; idy < y.size(); ++idy)