Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ if(EMSCRIPTEN)
set(CPPINTEROP_EXTRA_WASM_FLAGS "-fwasm-exceptions" CACHE STRING "Extra flags for wasm")
endif()

# Clad plugin options
option(CPPINTEROP_ENABLE_CLAD "Enable the Clad automatic differentiation plugin." OFF)
set(CLAD_BUILD_TYPE "Release" CACHE STRING "Build type for clad plugins")

if (CPPINTEROP_USE_CLING AND CPPINTEROP_USE_REPL)
message(FATAL_ERROR "We can only use Cling (${CPPINTEROP_USE_CLING}=On) or Repl (CPPINTEROP_USE_REPL=On), but not both of them.")
endif()
Expand Down Expand Up @@ -526,6 +530,12 @@ if (CPPINTEROP_INCLUDE_DOCS)
add_subdirectory(docs)
endif()

if(CPPINTEROP_ENABLE_CLAD)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No real work has been done so far to enable building Clad using Emscripten, so you probably want the configure to error out if CPPINTEROP_ENABLE_CLAD is set to on, and EMSCRIPTEN is true.

message(STATUS "CPPINTEROP_ENABLE_CLAD is ON: Building CppInterOp Clad plugin.")
message(STATUS "Clad build type: ${CLAD_BUILD_TYPE}")
add_subdirectory(plugins/clad)
endif()

add_subdirectory(lib)
if (CPPINTEROP_ENABLE_TESTING)
add_subdirectory(unittests)
Expand Down
23 changes: 21 additions & 2 deletions lib/CppInterOp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,18 @@ if (LLVM_LINK_LLVM_DYLIB)
)
endif(LLVM_LINK_LLVM_DYLIB)

if(CPPINTEROP_ENABLE_CLAD)
set(CPPINTEROP_PLUGIN_LINK_LIBS)
if (APPLE)
set(CPPINTEROP_PLUGIN_LINK_LIBS -Wl,-force_load cladPlugin -Wl,-force_load cladDifferentiator)
elseif(MSVC)
set(CPPINTEROP_PLUGIN_LINK_LIBS cladPlugin cladDifferentiator)
set(CLAD_LIBS "-WHOLEARCHIVE:cladPlugin.lib -WHOLEARCHIVE:cladDifferentiator.lib")
else()
set(CPPINTEROP_PLUGIN_LINK_LIBS -Wl,--whole-archive cladPlugin cladDifferentiator -Wl,--no-whole-archive)
endif()
endif(CPPINTEROP_ENABLE_CLAD)

add_llvm_library(clangCppInterOp
DISABLE_LLVM_LINK_LLVM_DYLIB
CppInterOp.cpp
Expand All @@ -112,6 +124,7 @@ add_llvm_library(clangCppInterOp
${DLM}
LINK_LIBS
${link_libs}
${CPPINTEROP_PLUGIN_LINK_LIBS}
)

if(EMSCRIPTEN)
Expand Down Expand Up @@ -161,6 +174,12 @@ endif(EMSCRIPTEN)
target_compile_definitions(clangCppInterOp PUBLIC "_CINDEX_LIB_") # workaround for the use of `CINDEX_LINKAGE`

string(REPLACE ";" "\;" _VER CPPINTEROP_VERSION)
set_source_files_properties(CppInterOp.cpp PROPERTIES COMPILE_DEFINITIONS
"LLVM_BINARY_DIR=\"${LLVM_BINARY_DIR}\";CPPINTEROP_VERSION=\"${_VAR}\""
set_property(SOURCE CppInterOp.cpp APPEND PROPERTY COMPILE_DEFINITIONS
"LLVM_BINARY_DIR=\"${LLVM_BINARY_DIR}\""
"CPPINTEROP_VERSION=\"${_VAR}\""
)

set_property(SOURCE CppInterOp.cpp APPEND PROPERTY COMPILE_DEFINITIONS
"CLAD_INCLUDE_DIRS=\"${CMAKE_BINARY_DIR}/plugins/clad/include/\""
"CPPINTEROP_ENABLE_CLAD=\"${CPPINTEROP_ENABLE_CLAD}\""
)
3 changes: 3 additions & 0 deletions lib/CppInterOp/CppInterOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3455,6 +3455,9 @@ TInterp_t CreateInterpreter(const std::vector<const char*>& Args /*={}*/,
*I, "__clang_Interpreter_SetValueNoAlloc",
reinterpret_cast<uint64_t>(&__clang_Interpreter_SetValueNoAlloc));
#endif
if(CPPINTEROP_ENABLE_CLAD) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: implicit conversion turns string literal into bool: 'const char[4]' to 'bool' [clang-diagnostic-string-conversion]

  if(CPPINTEROP_ENABLE_CLAD) {
     ^

expanded from macro 'CPPINTEROP_ENABLE_CLAD'

Cpp::AddIncludePath(CLAD_INCLUDE_DIRS);
}
return I;
}

Expand Down
95 changes: 95 additions & 0 deletions plugins/clad/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
include(ExternalProject)

set(clad_install_dir ${CMAKE_BINARY_DIR}/plugins/clad/)
# Specify include dirs for clad
set(CLAD_INCLUDE_DIRS ${clad_install_dir})
# Clad Libraries
set(CLAD_CXX_FLAGS ${CMAKE_CXX_FLAGS})
set(_clad_build_type ${CLAD_BUILD_TYPE})
if(MSVC AND NOT CMAKE_GENERATOR MATCHES Ninja)
if (winrtdebug)
set(_clad_build_type Debug)
else()
set(_clad_build_type Release)
endif()
if(asan)
set(CLAD_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ASAN_EXTRA_CXX_FLAGS}")
endif()
set(EXTRA_BUILD_ARGS --config ${_clad_build_type})
endif()
if(NOT _clad_build_type STREQUAL "" AND NOT _clad_build_type STREQUAL ".")
set(EXTRA_BUILD_ARGS --config ${_clad_build_type})
endif()

set(_CLAD_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR}/clad-prefix/src/clad-build/lib/)

# build byproducts only needed by Ninja
if(CMAKE_GENERATOR MATCHES Ninja)
set(CLAD_BYPRODUCTS
${_CLAD_LIBRARY_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}cladPlugin${CMAKE_STATIC_LIBRARY_SUFFIX}
${_CLAD_LIBRARY_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}cladDifferentiator${CMAKE_STATIC_LIBRARY_SUFFIX}
)
endif()

if(APPLE)
set(_clad_extra_cmake_args -DCMAKE_OSX_SYSROOT=${CMAKE_OSX_SYSROOT})
endif()

if (CMAKE_CXX_STANDARD)
list(APPEND _clad_extra_cmake_args -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD})
endif(CMAKE_CXX_STANDARD)

if (LLVM_FORCE_USE_OLD_TOOLCHAIN)
list(APPEND _clad_extra_cmake_args -DLLVM_FORCE_USE_OLD_TOOLCHAIN=${LLVM_FORCE_USE_OLD_TOOLCHAIN})
endif(LLVM_FORCE_USE_OLD_TOOLCHAIN)

list(APPEND _clad_extra_cmake_args -DCLAD_BUILD_STATIC_ONLY=ON)

# Wrap download, configure and build steps in a script to log output
set(_clad_extra_settings
LOG_DOWNLOAD ON
LOG_CONFIGURE ON
LOG_BUILD ON
LOG_INSTALL ON
LOG_OUTPUT_ON_FAILURE ON
)

if (DEFINED CLAD_SOURCE_DIR)
message(STATUS "Using local clad source directory: ${CLAD_SOURCE_DIR}")
list(APPEND _clad_extra_settings SOURCE_DIR ${CLAD_SOURCE_DIR})
else()
list(APPEND _clad_extra_settings GIT_REPOSITORY https://github.com/vgvassilev/clad.git)
list(APPEND _clad_extra_settings GIT_TAG v2.2)
endif()

message(STATUS "CMAKE_COMMAND: ${CMAKE_COMMAND}")
message(STATUS "EXTRA_BUILD_ARGS: ${EXTRA_BUILD_ARGS}")

ExternalProject_Add(
clad
UPDATE_COMMAND ""
CMAKE_ARGS -G ${CMAKE_GENERATOR}
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_CXX_FLAGS=${CLAD_CXX_FLAGS}
-DCMAKE_CXX_FLAGS_DEBUG=${CMAKE_CXX_FLAGS_DEBUG}
-DCMAKE_INSTALL_PREFIX=${clad_install_dir}
-DLLVM_DIR=${LLVM_DIR}
-DClang_DIR=${CLANG_CMAKE_DIR}
${_clad_extra_cmake_args}
BUILD_COMMAND ${CMAKE_COMMAND} --build . ${EXTRA_BUILD_ARGS} --parallel
INSTALL_COMMAND ${CMAKE_COMMAND} --build . ${EXTRA_BUILD_ARGS} --target install
BUILD_BYPRODUCTS ${CLAD_BYPRODUCTS}
${_clad_extra_settings}
)

# Register cladPlugin, cladDifferentiator
foreach (lib cladPlugin cladDifferentiator)
add_library(${lib} IMPORTED STATIC GLOBAL)
add_dependencies(${lib} clad)
endforeach()

set_property(TARGET cladPlugin PROPERTY IMPORTED_LOCATION ${_CLAD_LIBRARY_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}cladPlugin${CMAKE_STATIC_LIBRARY_SUFFIX})
set_property(TARGET cladDifferentiator PROPERTY IMPORTED_LOCATION ${_CLAD_LIBRARY_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}cladDifferentiator${CMAKE_STATIC_LIBRARY_SUFFIX})
6 changes: 5 additions & 1 deletion unittests/CppInterOp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ else()
endif()

add_cppinterop_unittest(CppInterOpTests
ENABLE_DISPATCH
# ENABLE_DISPATCH
CommentReflectionTest.cpp
CladTest.cpp
EnumReflectionTest.cpp
FunctionReflectionTest.cpp
InterpreterTest.cpp
Expand All @@ -33,6 +34,9 @@ endif ()
set_source_files_properties(InterpreterTest.cpp PROPERTIES COMPILE_DEFINITIONS
"LLVM_BINARY_DIR=\"${LLVM_BINARY_DIR}\""
)
set_source_files_properties(CladTest.cpp PROPERTIES COMPILE_DEFINITIONS
"CLAD_INCLUDE_DIRS=\"${CMAKE_BINARY_DIR}/plugins/clad/include/\""
)

if(EMSCRIPTEN)
string(REPLACE "@" "@@" ESCAPED_SYSROOT_PATH "${SYSROOT_PATH}")
Expand Down
32 changes: 32 additions & 0 deletions unittests/CppInterOp/CladTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "Utils.h"

#include "CppInterOp/CppInterOp.h"
#include "gtest/gtest.h"

using namespace TestUtils;
using namespace llvm;
using namespace clang;

// This should work
// TYPED_TEST(CppInterOpTest, CladTestSanity) {
// std::string code = R"(
// #include "CppInterOp/CppInterOp.h"
// )";

// auto I = Cpp::CreateInterpreter();
// Cpp::Declare(code.c_str());
// }

TYPED_TEST(CPPINTEROP_TEST_MODE, CladTest_Sanity) {
std::vector<Decl*> Decls;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "std::vector" is directly included [misc-include-cleaner]

unittests/CppInterOp/CladTest.cpp:1:

+ #include <vector>

std::string code = R"(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "std::string" is directly included [misc-include-cleaner]

unittests/CppInterOp/CladTest.cpp:1:

+ #include <string>

#include "clad/Differentiator/Differentiator.h"
static double pow2(double x) { return x * x; }
)";

auto I = Cpp::CreateInterpreter({"-std=c++17"}, {});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: 'auto I' can be declared as 'auto *I' [llvm-qualified-auto]

Suggested change
auto I = Cpp::CreateInterpreter({"-std=c++17"}, {});
auto *I = Cpp::CreateInterpreter({"-std=c++17"}, {});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unused variable 'I' [clang-diagnostic-unused-variable]

  auto I = Cpp::CreateInterpreter({"-std=c++17"}, {});
       ^

Cpp::Declare(code.c_str() DFLT_FALSE);

std::string code_diff = "clad::differentiate(pow2, 0).execute(3)";
ASSERT_EQ(Cpp::Evaluate(code_diff.c_str() DFLT_NULLPTR), 6);
}
Loading