diff --git a/.gitignore b/.gitignore index ec107200a..70de320f4 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,17 @@ examples/vgg/models/vgg16/*.npy new_sun.png new_sun*.png new_sun_hello.png -test/correspondence/gh.out \ No newline at end of file +test/correspondence/gh.out +!Makefile +!modules/* +modules/build +!bridge/* +bridge/build +bridge/libtorch +# pytorch/ +build/ +libtorch/ +.cache/ +build-release/ +libtorch_static/ +examples/vgg/**/*.pt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..870603c85 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,296 @@ +cmake_minimum_required(VERSION 3.31 FATAL_ERROR) +# project(MyProject LANGUAGES CXX) + +include(CMakePrintHelpers) + +# set(CMAKE_VERBOSE_MAKEFILE ON) + +if(UNIX AND NOT APPLE) + set(LINUX TRUE) +endif() + +set(PROJECT_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") +set(PROJECT_BINARY_DIR "${CMAKE_BINARY_DIR}") +set(PROJECT_CACHE_DIR "${PROJECT_ROOT_DIR}/.cache") +set(LIBTORCH_DIR "${PROJECT_ROOT_DIR}/libtorch") +# set(LIBTORCH_STATIC_INSTALL_DIR "${PROJECT_ROOT_DIR}/libtorch_static") +set(BRIDGE_DIR "${PROJECT_ROOT_DIR}/bridge") + + +find_package(chpl REQUIRED HINTS ${PROJECT_ROOT_DIR}/cmake/chapel) +list(APPEND CMAKE_MODULE_PATH "${PROJECT_ROOT_DIR}/cmake") +list(APPEND CMAKE_MODULE_PATH "${PROJECT_ROOT_DIR}/cmake/chapel") + +project(MyProject LANGUAGES CXX C CHPL) +message(STATUS "Using chpl: ${CMAKE_CHPL_COMPILER}") + + +if(APPLE) + set(CMAKE_C_COMPILER "/usr/bin/clang") + set(CMAKE_CXX_COMPILER "/usr/bin/clang++") +endif() +set(CMAKE_CXX_STANDARD 23) + + +include(LibTorchDL) +download_libtorch( + CACHE_DIR ${PROJECT_CACHE_DIR} + DESTINATION ${LIBTORCH_DIR} +) + + +include(FetchContent) +include(ExternalProject) + + +# if(NOT EXISTS "${LIBTORCH_STATIC_INSTALL_DIR}/lib/libtorch.a") +# ExternalProject_Add( +# pytorch +# GIT_REPOSITORY https://github.com/pytorch/pytorch.git +# GIT_TAG v2.6.0 # Example: specify a particular release +# UPDATE_COMMAND "" # Don’t auto-run 'git pull' +# PATCH_COMMAND "" # No custom patch step + +# # DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/pytorch-download" # Where to download the repo + +# # We need all PyTorch submodules. By default, ExternalProject won't do submodule init. +# # So we can do that in a separate step if we want a full build. For a minimal CPU build, +# # you might not need them all, but let's be safe: +# STEP_TARGETS clone +# # After 'clone', run "git submodule update --init --recursive" +# # to fetch all submodules. +# # We can use a little trick with COMMAND. +# # PATCH_COMMAND "git submodule update --init --recursive" + +# # CMAKE_ARGS +# # -DBUILD_SHARED_LIBS=OFF # Build static libraries +# # -DBUILD_PYTHON=OFF # Don’t build Python bindings +# # -DBUILD_TEST=OFF # Don’t build tests +# # -DUSE_CUDA=OFF # Disable CUDA +# # -DUSE_CUDNN=OFF # Disable cuDNN +# # -DUSE_MKLDNN=OFF # Disable MKLDNN for simplicity +# # # -DBUILD_BINARY=ON +# # # -DUSE_DISTRIBUTED=ON +# # # -DBUILD_STATIC_RUNTIME_BENCHMARK=ON +# # # -DBUILD_LITE_INTERPRETER=ON +# # # -DUSE_STATIC_MKL=ON +# # # -DSTATIC_DISPATCH_BACKEND=ON +# # # -DCAFFE2_USE_MSVC_STATIC_RUNTIME=ON +# # # -DUSE_DISTRIBUTED=ON +# # # -DCMAKE_BUILD_TYPE=Release +# # -DCMAKE_INSTALL_PREFIX=${PYTORCH_INSTALL_DIR} +# # # -DCMAKE_POLICY_VERSION_MINIMUM=3.5 +# CMAKE_ARGS +# -DBUILD_SHARED_LIBS=OFF # Build static libraries +# -DBUILD_PYTHON=OFF # Don’t build Python bindings +# -DBUILD_TEST=OFF # Don’t build tests +# -DUSE_CUDA=OFF # Disable CUDA +# -DUSE_CUDNN=OFF # Disable cuDNN +# -DUSE_MKLDNN=OFF # Disable MKLDNN for simplicity +# -DCMAKE_BUILD_TYPE=Release +# # -DSTATIC_DISPATCH_BACKEND=ON +# -DCMAKE_INSTALL_PREFIX=${LIBTORCH_STATIC_INSTALL_DIR} +# -DCMAKE_POLICY_VERSION_MINIMUM=3.5 + +# INSTALL_DIR ${LIBTORCH_STATIC_INSTALL_DIR} # Where to install +# ) +# endif() + + +file(GLOB CHAI_LIB_FILES "${PROJECT_ROOT_DIR}/lib/*.chpl") + +# file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/resources_dummy.c "int main(int argc, const char **argv){ return 1; }\n") +# add_executable(ChAI ${CMAKE_CURRENT_BINARY_DIR}/resources_dummy.c) +# # file(GLOB RESOURCE_FILES *.bmp *.wav moose.dat utf8.txt) +# foreach(RESOURCE_FILE ${CHAI_LIB_FILES}) +# add_custom_command( +# TARGET ChAI +# POST_BUILD +# COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${RESOURCE_FILE} $ +# ) +# endforeach(RESOURCE_FILE) + +# file(COPY ${CHAI_LIB_FILES} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + + + + +add_custom_target( + ChAI + ALL + DEPENDS ${PROJECT_SOURCE_DIR}/lib + # SOURCES ${CHAI_LIB_FILES} + # COMMAND ${CMAKE_COMMAND} -E echo "Building ChAI" +) + +foreach(RESOURCE_FILE ${CHAI_LIB_FILES}) + add_custom_command( + TARGET ChAI + POST_BUILD + # OUTPUT $ + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${RESOURCE_FILE} ${PROJECT_BINARY_DIR}/lib + # DEPENDS ${CHAI_LIB_FILES} + ) +endforeach(RESOURCE_FILE) + + + +# foreach(RESOURCE_FILE ${CHAI_LIB_FILES}) +# add_custom_command( +# TARGET ChAI +# POST_BUILD +# COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${RESOURCE_FILE} $ +# ) +# endforeach(RESOURCE_FILE) + + +function(watch) + set_property( + DIRECTORY + APPEND + PROPERTY CMAKE_CONFIGURE_DEPENDS ${ARGV} + ) +endfunction() + +# cmake_print_variables(CHAI_LIB_FILES) + +add_library(bridge STATIC ${BRIDGE_DIR}/include/bridge.h ${BRIDGE_DIR}/lib/bridge.cpp) + +target_include_directories( + bridge + PRIVATE + ${BRIDGE_DIR}/include + ${LIBTORCH_DIR}/include + ${LIBTORCH_DIR}/include/torch/csrc/api/include +) + +set(BRIDGE_OBJECT_FILES $) + + + + +file(GLOB LIBTORCH_ALL_LIB_FILES + "${LIBTORCH_DIR}/lib/*.a" + "${LIBTORCH_DIR}/lib/*.dylib" + "${LIBTORCH_DIR}/lib/*.so") + +set(LIBTORCH_ALL_LIBS "") +foreach(lib_path IN LISTS LIBTORCH_ALL_LIB_FILES) + get_filename_component(lib_name "${lib_path}" NAME_WE) + list(APPEND LIBTORCH_ALL_LIBS "${lib_name}") +endforeach() + + +set(REQUIRED_LIBS + "libtorch" + "libtorch_cpu" + "libc10" + "libtorch_global_deps" +) + +set(DISALLOWED_LIBS + "libtorch_python" +) + +set(LIBTORCH_LIBS_LINKER_ARGS "") # Will hold the list of "-l..." flags. +foreach(lib_name IN LISTS LIBTORCH_ALL_LIBS) + if(lib_name IN_LIST DISALLOWED_LIBS) + if(lib_name IN_LIST REQUIRED_LIBS) + message(FATAL_ERROR "Required lib ${lib_name} is disallowed.") + else() + message(STATUS "Skipping disallowed lib: ${lib_name}") + continue() + endif() + endif() + string(REGEX REPLACE "^lib" "" lib_name_short "${lib_name}") + list(APPEND LIBTORCH_LIBS_LINKER_ARGS "-l${lib_name_short}") +endforeach() + +# cmake_print_variables(LIBTORCH_LIBS_LINKER_ARGS) +# cmake_print_variables(${BRIDGE_OBJECT_FILES}) +# cmake_print_variables(BRIDGE_OBJECT_FILES) + + +add_executable(TorchBridge ${BRIDGE_DIR}/lib/Bridge.chpl) +add_dependencies(TorchBridge bridge) +add_dependencies(TorchBridge ChAI) +target_link_options(TorchBridge + PRIVATE + ${BRIDGE_DIR}/include/bridge.h + ${BRIDGE_OBJECT_FILES} + -L ${LIBTORCH_DIR}/lib + # "-ltorch" + # "-ltorch_cpu" + # "-lc10" + # "-ltorch_global_deps" + ${LIBTORCH_LIBS_LINKER_ARGS} + --ldflags "-Wl,-rpath,${LIBTORCH_DIR}/lib" +) + + + + +add_executable(TinyLayerTest + ${PROJECT_ROOT_DIR}/test/tiny/layer_test.chpl + ${CHAI_LIB_FILES} + ) +add_dependencies(TinyLayerTest bridge) +add_dependencies(TinyLayerTest ChAI) +target_link_options(TinyLayerTest + PRIVATE + --main-module layer_test.chpl + -M ${PROJECT_ROOT_DIR}/lib + ${BRIDGE_DIR}/include/bridge.h + ${BRIDGE_OBJECT_FILES} + -L ${LIBTORCH_DIR}/lib + ${LIBTORCH_LIBS_LINKER_ARGS} + --ldflags "-Wl,-rpath,${LIBTORCH_DIR}/lib" +) +# chpl test/tiny/layer_test.chpl -M lib bridge/include/bridge.h build/CMakeFiles/bridge.dir/bridge/lib/bridge.cpp.o -L libtorch/lib -ltorch -ltorch_cpu -lc10 -ltorch_global_deps --ldflags "-Wl,-rpath,libtorch/lib" + +# chpl --fast -o vgg test.chpl -M ../../lib /Users/iainmoncrief/Documents/Github/ChAI/bridge/include/bridge.h /Users/iainmoncrief/Documents/Github/ChAI/build/CMakeFiles/bridge.dir/bridge/lib/bridge.cpp.o -L /Users/iainmoncrief/Documents/Github/ChAI/libtorch/lib -ltorch -ltorch_cpu -lc10 -ltorch_global_deps --ldflags "-Wl,-rpath,/Users/iainmoncrief/Documents/Github/ChAI/libtorch/lib" + +# chpl -o vgg test.chpl $(../../embed_libtorch.sh .) +# chpl --fast -o vgg test.chpl $(../../embed_libtorch.sh .) + + + + +set(CHAI_LINKER_ARGS + -M ${PROJECT_ROOT_DIR}/lib + ${BRIDGE_DIR}/include/bridge.h + ${BRIDGE_OBJECT_FILES} + -L ${LIBTORCH_DIR}/lib + ${LIBTORCH_LIBS_LINKER_ARGS} + --ldflags "-Wl,-rpath,${LIBTORCH_DIR}/lib" +) + + + +add_executable(vgg + "${PROJECT_ROOT_DIR}/examples/vgg/test.chpl" + ${PROJECT_ROOT_DIR}/examples/vgg/VGG.chpl + ${CHAI_LIB_FILES} +) +add_dependencies(vgg bridge) +add_dependencies(vgg ChAI) +target_link_options(vgg + PRIVATE + # -M ${PROJECT_ROOT_DIR}/examples/vgg + -svggExampleDir="${PROJECT_ROOT_DIR}/examples/vgg" + ${CHAI_LINKER_ARGS} +) + +add_custom_command( + TARGET vgg + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + "${PROJECT_ROOT_DIR}/examples/vgg/images" + "$/images" + COMMENT "Copying ${PROJECT_ROOT_DIR}/examples/vgg/images to $/images" +) + +# ./vgg images/frog.jpg + +add_subdirectory(examples) +add_subdirectory("test") diff --git a/bridge/.DS_Store b/bridge/.DS_Store new file mode 100644 index 000000000..3a6750191 Binary files /dev/null and b/bridge/.DS_Store differ diff --git a/bridge/CMakeLists.txt b/bridge/CMakeLists.txt new file mode 100644 index 000000000..ebe1f4ef3 --- /dev/null +++ b/bridge/CMakeLists.txt @@ -0,0 +1,223 @@ +cmake_minimum_required(VERSION 3.31 FATAL_ERROR) +# project(MyProject LANGUAGES CXX) + +include(CMakePrintHelpers) + +# set(CMAKE_VERBOSE_MAKEFILE ON) + +if(UNIX AND NOT APPLE) + set(LINUX TRUE) +endif() + +set(CMAKE_C_COMPILER "clang") +set(CMAKE_CXX_COMPILER "clang++") +set(CMAKE_CXX_STANDARD 17) + + +set(PROJECT_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") +set(PROJECT_BINARY_DIR "${CMAKE_BINARY_DIR}") + + +# For ExternalProject_Add +include(FetchContent) +include(ExternalProject) + +# ------------------------------------------------------------------------------ +# 1) External project: build PyTorch (libtorch) from source as STATIC +# ------------------------------------------------------------------------------ + +# Where to place PyTorch after installation +# set(PYTORCH_INSTALL_DIR "${PROJECT_BINARY_DIR}/pytorch-install") +# set(PYTORCH_BUILD_DIR "${PROJECT_BINARY_DIR}/pytorch-prefix/src/pytorch-build") + +# set(PYTORCH_INSTALL_PREFIX "${PROJECT_BINARY_DIR}/pytorch-install-prefix") +# file(MAKE_DIRECTORY "${PYTORCH_INSTALL_PREFIX}") + +# ExternalProject_Add can fetch from Git, a local path, or a release tarball. +# Here, for simplicity, we'll fetch from Git. In practice, you might want +# a fixed commit or a release tarball for reproducible builds. + +# ExternalProject_Add( +# pytorch +# GIT_REPOSITORY https://github.com/pytorch/pytorch.git +# GIT_TAG v2.6.0 # Example: specify a particular release +# UPDATE_COMMAND "" # Don’t auto-run 'git pull' +# PATCH_COMMAND "" # No custom patch step + +# # DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/pytorch-download" # Where to download the repo + +# # We need all PyTorch submodules. By default, ExternalProject won't do submodule init. +# # So we can do that in a separate step if we want a full build. For a minimal CPU build, +# # you might not need them all, but let's be safe: +# STEP_TARGETS clone +# # After 'clone', run "git submodule update --init --recursive" +# # to fetch all submodules. +# # We can use a little trick with COMMAND. +# # PATCH_COMMAND "git submodule update --init --recursive" + +# # CMAKE_ARGS +# # -DBUILD_SHARED_LIBS=OFF # Build static libraries +# # -DBUILD_PYTHON=OFF # Don’t build Python bindings +# # -DBUILD_TEST=OFF # Don’t build tests +# # -DUSE_CUDA=OFF # Disable CUDA +# # -DUSE_CUDNN=OFF # Disable cuDNN +# # -DUSE_MKLDNN=OFF # Disable MKLDNN for simplicity +# # # -DBUILD_BINARY=ON +# # # -DUSE_DISTRIBUTED=ON +# # # -DBUILD_STATIC_RUNTIME_BENCHMARK=ON +# # # -DBUILD_LITE_INTERPRETER=ON +# # # -DUSE_STATIC_MKL=ON +# # # -DSTATIC_DISPATCH_BACKEND=ON +# # # -DCAFFE2_USE_MSVC_STATIC_RUNTIME=ON +# # # -DUSE_DISTRIBUTED=ON +# # # -DCMAKE_BUILD_TYPE=Release +# # -DCMAKE_INSTALL_PREFIX=${PYTORCH_INSTALL_DIR} +# # # -DCMAKE_POLICY_VERSION_MINIMUM=3.5 +# CMAKE_ARGS +# -DBUILD_SHARED_LIBS=OFF # Build static libraries +# -DBUILD_PYTHON=OFF # Don’t build Python bindings +# -DBUILD_TEST=OFF # Don’t build tests +# -DUSE_CUDA=OFF # Disable CUDA +# -DUSE_CUDNN=OFF # Disable cuDNN +# -DUSE_MKLDNN=OFF # Disable MKLDNN for simplicity +# -DCMAKE_BUILD_TYPE=Release +# -DCMAKE_INSTALL_PREFIX=${PYTORCH_INSTALL_DIR} + +# INSTALL_DIR ${PYTORCH_INSTALL_DIR} # Where to install + +# # LOG_DOWNLOAD ON +# # LOG_UPDATE ON +# # LOG_PATCH ON +# # LOG_CONFIGURE ON +# # LOG_BUILD ON +# # LOG_INSTALL ON + +# ) + +set(PYTORCH_INSTALL_DIR "${PROJECT_ROOT_DIR}/libtorch") +# file(GLOB_RECURSE PYTORCH_INCLUDES "${PYTORCH_INSTALL_DIR}/include" "*.h") +# file(GLOB_RECURSE PYTORCH_LIBS "${PYTORCH_INSTALL_DIR}/lib" "*.a") + + +# set(PYTORCH_LIBS_LINKER_ARGS "-L/Users/jade/Development/libtorch/libtorch/lib") # Will hold the list of "-l..." flags. +# foreach(lib_path IN LISTS PYTORCH_LIBS) +# # Get just the filename without the directory or extension +# get_filename_component(lib_name "${lib_path}" NAME_WE) +# # If it starts with "lib", strip that off +# string(REGEX REPLACE "^lib" "" lib_name "${lib_name}") +# # Now prepend "-l" to the actual library name +# list(APPEND MY_LIBS "-l${lib_name}") +# endforeach() + + +find_package(chpl REQUIRED HINTS ${PROJECT_ROOT_DIR}/cmake/chapel) +list(APPEND CMAKE_MODULE_PATH "${PROJECT_ROOT_DIR}/cmake") +list(APPEND CMAKE_MODULE_PATH "${PROJECT_ROOT_DIR}/cmake/chapel") + +project(MyProject LANGUAGES CXX C CHPL) + +# ------------------------------------------------------------------------------ +# 2) Create an INTERFACE library to wrap the installed static libs +# ------------------------------------------------------------------------------ + +# We'll create a dummy target that depends on 'pytorch' so that +# building your own code will first build/install PyTorch. + +# add_library(torch_interface INTERFACE) + +# # Ensure that our 'torch_interface' target isn't used until PyTorch is built +# # add_dependencies(torch_interface pytorch) + +# # Include directories for PyTorch +# target_include_directories(torch_interface INTERFACE +# "${PYTORCH_INSTALL_DIR}/include" +# "${PYTORCH_INSTALL_DIR}/include/torch/csrc/api/include" +# # "${PYTORCH_BUILD_DIR}/aten/src/include" +# ) + +# # Link the relevant static libraries. For a minimal CPU-only build, +# # you'll likely need at least these (names can vary by version). +# # The exact set can differ depending on which components got built. + +# target_link_libraries(torch_interface INTERFACE +# "${PYTORCH_INSTALL_DIR}/lib/libtorch.a" +# "${PYTORCH_INSTALL_DIR}/lib/libtorch_cpu.a" +# "${PYTORCH_INSTALL_DIR}/lib/libc10.a" + +# # ${PYTORCH_LIBS} + +# # System libraries often needed: +# pthread +# dl +# rt +# ) + + + +add_executable(CHPLTest lib/CHPLTest.chpl) + + +add_library(torchbridge OBJECT "${PROJECT_ROOT_DIR}/lib/bridge.cpp" "${PROJECT_ROOT_DIR}/include/bridge.h") +# add_dependencies(torchbridge torch_interface) + +target_include_directories(torchbridge PRIVATE + "${PYTORCH_INSTALL_DIR}/include" + "${PYTORCH_INSTALL_DIR}/include/torch/csrc/api/include" + "${PROJECT_ROOT_DIR}/include" +# # "${PYTORCH_BUILD_DIR}/aten/src/include" +) +# target_link_directories(torchbridge PUBLIC +# "${PYTORCH_INSTALL_DIR}/lib" +# ) +# target_link_libraries(torchbridge +# PRIVATE +# # torch_interface +# # ${PYTORCH_LIBS} + +# pthread +# dl +# rt +# ) + + + + + +add_executable(Bridge lib/Bridge.chpl include/bridge.h) +# add_dependencies(TorchBridge torchbridge) +add_dependencies(Bridge torchbridge) + +target_link_options(Bridge + PRIVATE + "${PROJECT_ROOT_DIR}/include/bridge.h" + "-L${PROJECT_BINARY_DIR}" + # "-ltorchbridge" + # -L. + "-ltorchbridge" + # "-I${PROJECT_BINARY_DIR}" + "-L${PYTORCH_INSTALL_DIR}/lib" + # "-I${PYTORCH_INSTALL_DIR}/include" + # "-I${PYTORCH_INSTALL_DIR}/include/torch/csrc/api/include" + "-ltorch" + "-ltorch_cpu" + # "-lcpuinfo" + "-lc10" + # "-lsleef" + # "-lclog" + # "-lprotoc" + # ${PYTORCH_LIBS_LINKER_ARGS} + # "-lpthread" + # "-ldl" + ) + + + +# ------------------------------------------------------------------------------ +# 3) Build your own executable that uses torch_interface +# ------------------------------------------------------------------------------ + +# add_executable(my_app src/main.cpp) + +# # Link your app against our interface library +# target_link_libraries(my_app PRIVATE torch_interface) + diff --git a/bridge/Fix.txt b/bridge/Fix.txt new file mode 100644 index 000000000..608e10be6 --- /dev/null +++ b/bridge/Fix.txt @@ -0,0 +1,4 @@ + +https://github.com/pytorch/pytorch/issues/20030 + +install_name_tool -add_rpath /opt/homebrew/opt/libomp/lib /Users/iainmoncrief/Documents/Github/ChAI/bridge/libtorch/lib/libtorch_cpu.dylib \ No newline at end of file diff --git a/bridge/Makefile b/bridge/Makefile new file mode 100644 index 000000000..079b6701e --- /dev/null +++ b/bridge/Makefile @@ -0,0 +1,21 @@ + +CXX = /usr/bin/clang++ +PWD = $(shell pwd) +LIBTORCH = $(PWD)/libtorch + +all: bridge.o Bridge + +bridge.o: lib/bridge.cpp include/bridge.h + $(CXX) -c lib/bridge.cpp -I include -o bridge.o -I $(LIBTORCH)/include/torch/csrc/api/include -I $(LIBTORCH)/include --std=c++17 + +# g++ -c lib/bridge.cpp -I include -o bridge.o -I /Users/iainmoncrief/Documents/Github/ChAI/bridge/libtorch/include/torch/csrc/api/include -I /Users/iainmoncrief/Documents/Github/ChAI/bridge/libtorch/include --std=c++17 + +Bridge: bridge.o lib/Bridge.chpl + chpl lib/Bridge.chpl include/bridge.h bridge.o -L $(LIBTORCH)/lib -ltorch -ltorch_cpu -lc10 --ldflags "-Wl,-rpath,$(LIBTORCH)/lib" + +clean: + rm -f bridge.o + rm -f Bridge + + + diff --git a/bridge/cmake/chapel/CMakeCHPLCompiler.cmake.in b/bridge/cmake/chapel/CMakeCHPLCompiler.cmake.in new file mode 100644 index 000000000..cc000ad9e --- /dev/null +++ b/bridge/cmake/chapel/CMakeCHPLCompiler.cmake.in @@ -0,0 +1,22 @@ +# Copyright 2023-2025 Hewlett Packard Enterprise Development LP +# Other additional copyright holders may be indicated within. +# +# The entirety of this work is licensed under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(CMAKE_CHPL_COMPILER "@CMAKE_CHPL_COMPILER@") +set(CMAKE_CHPL_COMPILER_LOADED 1) +set(CMAKE_CHPL_SOURCE_FILE_EXTENSIONS "@CMAKE_CHPL_SOURCE_FILE_EXTENSIONS@") +set(CMAKE_CHPL_OUTPUT_EXTENSION "@CMAKE_CHPL_OUTPUT_EXTENSION@") +set(CMAKE_CHPL_COMPILER_ENV_VAR "@CMAKE_CHPL_COMPILER_ENV_VAR@") diff --git a/bridge/cmake/chapel/CMakeCHPLInformation.cmake b/bridge/cmake/chapel/CMakeCHPLInformation.cmake new file mode 100644 index 000000000..2448ff1f5 --- /dev/null +++ b/bridge/cmake/chapel/CMakeCHPLInformation.cmake @@ -0,0 +1,32 @@ +# Copyright 2023-2025 Hewlett Packard Enterprise Development LP +# Other additional copyright holders may be indicated within. +# +# The entirety of this work is licensed under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# TODO: this is a hack, how do we tell cmake that we can't compile to object files? +set(CMAKE_CHPL_COMPILE_OBJECT "test -f || ln -s ") +set(CMAKE_CHPL_LINK_EXECUTABLE " -o ") +# doesn't work on link step + +# TODO: support --library directly to build Chapel shared libs for interoperability + +set(CMAKE_CHPL_SOURCE_FILE_EXTENSIONS chpl) + +set(CMAKE_CHPL_OUTPUT_EXTENSION ".chpl") + + +set(CMAKE_CHPL_FLAGS_RELEASE "--fast") +set(CMAKE_CHPL_FLAGS_DEBUG "-g") diff --git a/bridge/cmake/chapel/CMakeDetermineCHPLCompiler.cmake b/bridge/cmake/chapel/CMakeDetermineCHPLCompiler.cmake new file mode 100644 index 000000000..85e59b346 --- /dev/null +++ b/bridge/cmake/chapel/CMakeDetermineCHPLCompiler.cmake @@ -0,0 +1,46 @@ +# Copyright 2023-2025 Hewlett Packard Enterprise Development LP +# Other additional copyright holders may be indicated within. +# +# The entirety of this work is licensed under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# if there is an env CHPL_HOME, use it to find printchplenv +if (DEFINED ENV{CHPL_HOME}) + set(CHPL_HOME $ENV{CHPL_HOME}) + + execute_process( + COMMAND ${CHPL_HOME}/util/printchplenv --value --only CHPL_HOST_BIN_SUBDIR + OUTPUT_VARIABLE CHPL_HOST_BIN_SUBDIR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + set(CHPL_HOME_BIN_PATH ${CHPL_HOME}/bin/${CHPL_HOST_BIN_SUBDIR}) + # TODO: what if its a prefix install? +else() + set(CHPL_HOME "") + set(CHPL_HOME_BIN_PATH "") +endif() + +find_program( + CMAKE_CHPL_COMPILER + NAMES "chpl" + HINTS ${CHPL_HOME} ${CHPL_HOME_BIN_PATH} + DOC "chpl compiler" +) +# TODO: how to find chpl with just CHPL_HOME? + +set(CMAKE_CHPL_COMPILER_ENV_VAR "") + +configure_file(${CMAKE_CURRENT_LIST_DIR}/CMakeCHPLCompiler.cmake.in + ${CMAKE_PLATFORM_INFO_DIR}/CMakeCHPLCompiler.cmake) diff --git a/bridge/cmake/chapel/CMakeTestCHPLCompiler.cmake b/bridge/cmake/chapel/CMakeTestCHPLCompiler.cmake new file mode 100644 index 000000000..20cd8a372 --- /dev/null +++ b/bridge/cmake/chapel/CMakeTestCHPLCompiler.cmake @@ -0,0 +1,19 @@ +# Copyright 2023-2025 Hewlett Packard Enterprise Development LP +# Other additional copyright holders may be indicated within. +# +# The entirety of this work is licensed under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# For now do nothing +set(CMAKE_CHPL_COMPILER_WORKS 1 CACHE INTERNAL "") diff --git a/bridge/cmake/chapel/README.md b/bridge/cmake/chapel/README.md new file mode 100644 index 000000000..bb3cff024 --- /dev/null +++ b/bridge/cmake/chapel/README.md @@ -0,0 +1,17 @@ +# chpl CMake Support + +This directory contains the necessary files to support building Chapel programs using CMake. + +Take the following steps to use Chapel with CMake: + +1. Copy the files in this directory to your project's source directory. You may want to copy the files to a subdirectory like `cmake`, or you can just copy them to the root of your project. +2. Add `find_package(chpl REQUIRED HINTS .)` to your `CMakeLists.txt` file. + +Here is an example `CMakeLists.txt` file for a minimal Hello World program: + +```cmake +find_package(chpl REQUIRED HINTS .) +project(hello LANGUAGES CHPL) + +add_executable(hello hello.chpl) +``` diff --git a/bridge/cmake/chapel/chpl-config.cmake b/bridge/cmake/chapel/chpl-config.cmake new file mode 100644 index 000000000..145770e2a --- /dev/null +++ b/bridge/cmake/chapel/chpl-config.cmake @@ -0,0 +1,18 @@ +# Copyright 2023-2025 Hewlett Packard Enterprise Development LP +# Other additional copyright holders may be indicated within. +# +# The entirety of this work is licensed under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/bridge/include/bridge.h b/bridge/include/bridge.h new file mode 100644 index 000000000..d72454d81 --- /dev/null +++ b/bridge/include/bridge.h @@ -0,0 +1,92 @@ +#ifndef BRIDGE_H +#define BRIDGE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef float float32_t; +typedef double float64_t; +typedef char bool_t; +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; + +typedef struct bridge_tensor_t { + float* data; + int* sizes; + int dim; + bool_t created_by_c; +} bridge_tensor_t; + + +typedef struct nil_scalar_tensor_t { + float scalar; + bridge_tensor_t tensor; + bool_t is_nil; + bool_t is_scalar; + bool_t is_tensor; +} nil_scalar_tensor_t; + +float* unsafe(const float* arr); +bridge_tensor_t load_tensor_from_file(const uint8_t* file_path); +bridge_tensor_t load_tensor_dict_from_file(const uint8_t* file_path,const uint8_t* tensor_key); +bridge_tensor_t load_run_model(const uint8_t* model_path, bridge_tensor_t input); + + +int baz(void); + +void wrHello(void); + +void wrHelloTorch(void); + +float sumArray(float* arr, int* sizes, int dim); + +void increment(float* arr, int* sizes, int dim, float* output); +bridge_tensor_t increment2(float* arr, int* sizes, int dim); +bridge_tensor_t increment3(bridge_tensor_t arr); + +bridge_tensor_t convolve2d( + bridge_tensor_t input, + bridge_tensor_t kernel, + bridge_tensor_t bias, + int stride, + int padding +); + +bridge_tensor_t conv2d( + bridge_tensor_t input, + bridge_tensor_t kernel, + bridge_tensor_t bias, + int stride, + int padding +); + +bridge_tensor_t matmul(bridge_tensor_t a, bridge_tensor_t b); + +bridge_tensor_t max_pool2d( + bridge_tensor_t input, + int kernel_size, + int stride, + int padding, + int dilation +); + + +// bridge_tensor_t conv2d( +// bridge_tensor_t input, +// bridge_tensor_t kernel, +// nil_scalar_tensor_t bias, +// nil_scalar_tensor_t stride, +// nil_scalar_tensor_t padding +// ); + + + +#ifdef __cplusplus +} +#endif + +#endif // BRIDGE_H +//hello \ No newline at end of file diff --git a/bridge/jade.sh b/bridge/jade.sh new file mode 100644 index 000000000..9e5f5f8a4 --- /dev/null +++ b/bridge/jade.sh @@ -0,0 +1,7 @@ + + + + + + + diff --git a/bridge/lib/Bridge.chpl b/bridge/lib/Bridge.chpl new file mode 100644 index 000000000..6504b1afc --- /dev/null +++ b/bridge/lib/Bridge.chpl @@ -0,0 +1,193 @@ + +// require "mylib.h", "-lMyLib"; +use Allocators; + +extern proc baz(): int; +extern proc wrHello(): void; +extern proc wrHelloTorch(): void; +extern proc sumArray(arr: [] real(32), sizes: [] int(32), dim: int(32)): real(32); +extern proc increment(arr: [] real(32), sizes: [] int(32), dim: int(32), ref output: [] real(32)): void; + +extern record bridge_tensor_t { + var data: c_ptr(real(32)); + var sizes: c_ptr(int(32)); + var dim: int(32); +} + + + +extern proc increment2(arr: [] real(32), sizes: [] int(32), dim: int(32)): bridge_tensor_t; +extern proc increment3(in arr: bridge_tensor_t): bridge_tensor_t; + +extern proc convolve2d( + in input: bridge_tensor_t, + in kernel: bridge_tensor_t, + in bias: bridge_tensor_t, + in stride: int(32), + in padding: int(32)): bridge_tensor_t; + +extern proc unsafe(const ref arr: [] real(32)): c_ptr(real(32)); + +// baz(); + +// wrHello(); + + +// wrHelloTorch(); + +// writeln("baz: ", baz()); + + +var dom = {0..<10, 0..<10}; +var a: [dom] real(32); +for (idx,i) in zip(dom,0.. + +#include +#include + +// #include +// #include +#include +#include +#include +#include +#include +#include +#include +#include + + + + +int bridge_tensor_elements(bridge_tensor_t &bt) { + int size = 1; + for (int i = 0; i < bt.dim; ++i) { + size *= bt.sizes[i]; + } + return size; +} + +size_t bridge_tensor_size(bridge_tensor_t &bt) { + return sizeof(float32_t) * bridge_tensor_elements(bt); +} + +void store_tensor(torch::Tensor &input, float32_t* dest) { + float32_t * data = input.data_ptr(); + size_t bytes_size = sizeof(float32_t) * input.numel(); + std::memmove(dest,data,bytes_size); +} + +bridge_tensor_t torch_to_bridge(torch::Tensor &tensor) { + bridge_tensor_t result; + result.created_by_c = true; + result.dim = tensor.dim(); + result.sizes = new int[result.dim]; + for (int i = 0; i < result.dim; ++i) { + result.sizes[i] = tensor.size(i); + } + result.data = new float32_t[bridge_tensor_elements(result)]; + store_tensor(tensor, result.data); + return result; +} + +torch::Tensor bridge_to_torch(bridge_tensor_t &bt) { + std::vector sizes_vec(bt.sizes, bt.sizes + bt.dim); + auto shape = at::IntArrayRef(sizes_vec); + return torch::from_blob(bt.data, shape, torch::kFloat); +} + + + + + + + + + + + + + +extern "C" float32_t* unsafe(const float32_t* arr) { + return const_cast(arr); +} + +std::vector get_the_bytes(std::string filename) { + std::ifstream input(filename, std::ios::binary); + std::vector bytes((std::istreambuf_iterator(input)),(std::istreambuf_iterator())); + input.close(); + return bytes; +} + +extern "C" bridge_tensor_t load_tensor_from_file(const uint8_t* file_path) { + // // Load the tensor from a file + // torch::Tensor tensor; + // torch::load(tensor,file_path); + + // std::cout << "Tensor loaded from file: " << tensor.sizes() << std::endl; + + std::string fp(reinterpret_cast(file_path)); + std::vector f = get_the_bytes(fp); + torch::IValue x = torch::pickle_load(f); + torch::Tensor t = x.toTensor(); + return torch_to_bridge(t); +} + +extern "C" bridge_tensor_t load_tensor_dict_from_file(const uint8_t* file_path,const uint8_t* tensor_key) { + std::string fp(reinterpret_cast(file_path)); + std::string tk(reinterpret_cast(tensor_key)); + + torch::jit::script::Module container = torch::jit::load(fp); + torch::Tensor tensor = container.attr(tk).toTensor(); + + return torch_to_bridge(tensor); + +} + +extern "C" bridge_tensor_t load_run_model(const uint8_t* model_path, bridge_tensor_t input) { + auto t_input = bridge_to_torch(input); + std::string mp(reinterpret_cast(model_path)); + + std::cout << "Loading model from path: " << mp << std::endl; + std::cout.flush(); + + + torch::jit::Module module; + try + { + // Deserialize the ScriptModule from a file using torch::jit::load(). + module = torch::jit::load(mp); + } + catch (const c10::Error& e) + { + std::cerr << "error loading the model\n" << e.msg(); + std::system("pause"); + } + + std::vector inputs; + inputs.push_back(t_input); + + auto output = module.forward(inputs).toTensor(); + + std::cout << "Model output: " << output.sizes() << std::endl; + return torch_to_bridge(output); +} + + + + + + + + + + +extern "C" bridge_tensor_t increment3(bridge_tensor_t arr) { + auto t = bridge_to_torch(arr); + // Increment the tensor + auto incremented_tensor = t + 1; + + return torch_to_bridge(incremented_tensor); +} + +extern "C" bridge_tensor_t convolve2d( + bridge_tensor_t input, + bridge_tensor_t kernel, + bridge_tensor_t bias, + int stride, + int padding +) { + auto t_input = bridge_to_torch(input); + auto t_kernel = bridge_to_torch(kernel); + auto t_bias = bridge_to_torch(bias); + auto output = torch::conv2d(t_input, t_kernel, t_bias, stride, padding); + return torch_to_bridge(output); +} + +extern "C" bridge_tensor_t conv2d( + bridge_tensor_t input, + bridge_tensor_t kernel, + bridge_tensor_t bias, + int stride, + int padding +) { + auto t_input = bridge_to_torch(input); + auto t_kernel = bridge_to_torch(kernel); + auto t_bias = bridge_to_torch(bias); + auto output = torch::conv2d(t_input, t_kernel, t_bias, stride, padding); + return torch_to_bridge(output); +} + +extern "C" bridge_tensor_t matmul(bridge_tensor_t a, bridge_tensor_t b) { + auto t_a = bridge_to_torch(a); + auto t_b = bridge_to_torch(b); + auto output = torch::matmul(t_a, t_b); + + // std::cout << "Input A shape: " << t_a.sizes() << std::endl; + // std::cout << "Input B shape: " << t_b.sizes() << std::endl; + // std::cout << "Input A: " << t_a.sum() << std::endl; + // std::cout << "Input B: " << t_b.sum() << std::endl; + // // std::cout << "Input B: " << t_b << std::endl; + // std::cout << "Output shape: " << output.sizes() << std::endl; + // std::cout << "Output sum: " << output.sum() << std::endl; + // std::cout.flush(); + // printf("Hello from matmul!\n"); + + return torch_to_bridge(output); +} + +extern "C" bridge_tensor_t max_pool2d( + bridge_tensor_t input, + int kernel_size, + int stride, + int padding, + int dilation +) { + auto t_input = bridge_to_torch(input); + auto output = torch::max_pool2d(t_input, kernel_size, stride, padding); + return torch_to_bridge(output); +} + + +// extern "C" + + +// +// extern "C" bridge_tensor_t conv2d( +// bridge_tensor_t input, +// bridge_tensor_t kernel, +// nil_scalar_tensor_t bias, +// nil_scalar_tensor_t stride, +// nil_scalar_tensor_t padding +// ) { +// namespace F = torch::nn::functional; +// F::conv2d(input, kernel, F::Conv2dFuncOptions().stride(1)); +// } + + +extern "C" int baz(void) { + printf("Hello from baz!\n"); + auto x = torch::randn({5, 3}); + return x.size(0); +} + + +extern "C" void wrHello(void) { + printf("Hello from wrHello!\n"); +} + + +extern "C" void wrHelloTorch(void) { + printf("Hello from wrHelloTorch!\n"); + // auto t = torch::ones({2, 3}); + // std::cout << t << std::endl; +} + + + + +extern "C" void increment(float* arr, int* sizes, int dim, float* output) { + // Convert sizes to std::vector + std::vector sizes_vec(sizes, sizes + dim); + auto shape = at::IntArrayRef(sizes_vec); + auto t = torch::from_blob(arr, shape, torch::kFloat); + + // // Increment the tensor + // auto incremented_tensor = t + 1; + + // // Store the incremented tensor in the output array + // storeTensor(incremented_tensor, output); + + auto incremented_tensor = torch::from_blob(output, shape, torch::kFloat); + incremented_tensor.copy_(t + 1); +} + +extern "C" bridge_tensor_t increment2(float* arr, int* sizes, int dim) { + // Convert sizes to std::vector + std::vector sizes_vec(sizes, sizes + dim); + auto shape = at::IntArrayRef(sizes_vec); + auto t = torch::from_blob(arr, shape, torch::kFloat); + + // // Increment the tensor + // auto incremented_tensor = t + 1; + + // // Store the incremented tensor in the output array + // storeTensor(incremented_tensor, output); + + auto incremented_tensor = t + 1; + + return torch_to_bridge(incremented_tensor); +} + + +extern "C" float sumArray(float* arr, int* sizes, int dim) { + // Convert sizes to std::vector + + printf("sumArray called with arr: %p, sizes: %p, dim: %d\n", arr, sizes, dim); + + std::vector sizes_vec(sizes, sizes + dim); + std::cout << sizes_vec << std::endl; + + auto shape = at::IntArrayRef(sizes_vec); + std::cout << shape << std::endl; + + auto t = torch::from_blob(arr, shape, torch::kFloat); + std::cout << t << std::endl; + + return t.sum().item(); + + // return 0.0f; + + // float sum = 0.0f; + // for (int i = 0; i < size; ++i) { + // sum += arr[i]; + // } + // return sum; + // const std::vector sizes_vec(sizes, dim); + // auto shape = at::IntArrayRef(sizes_vec); + + // auto t = torch::from_blob(arr, shape, torch::kFloat); + // return t.sum().item(); +} \ No newline at end of file diff --git a/bridge/run.sh b/bridge/run.sh new file mode 100644 index 000000000..3abffc955 --- /dev/null +++ b/bridge/run.sh @@ -0,0 +1,3 @@ + +cmake -S . -B build +cmake --build build diff --git a/clib/Makefile b/clib/Makefile new file mode 100644 index 000000000..cce8dc9c3 --- /dev/null +++ b/clib/Makefile @@ -0,0 +1,18 @@ +all: myProgram + +myProgram: test.chpl libmylib.a #libmylib.a is the dependency for the executable + chpl -o myProgram test.chpl --ccflags mylib.h -L. -lmylib + +# gcc -lm -o myProgram main.o -L. -lmylib +# chpl mylib.h -L. -lmylib -o myProgram test.chpl + +mylib.o: mylib.c mylib.h + gcc -O -c mylib.c mylib.h + +libmylib.a: mylib.o + ar rcs libmylib.a mylib.o + +libs: libmylib.a + +clean: + rm -f myProgram *.o *.a *.gch #This way is cleaner than your clean \ No newline at end of file diff --git a/clib/libmylib.a b/clib/libmylib.a new file mode 100644 index 000000000..59eb228a8 Binary files /dev/null and b/clib/libmylib.a differ diff --git a/clib/mylib.c b/clib/mylib.c new file mode 100644 index 000000000..3ac021cfa --- /dev/null +++ b/clib/mylib.c @@ -0,0 +1,9 @@ + +#include "mylib.h" + +int myfunction(int a) { + return a + 1; +} + + + diff --git a/clib/mylib.h b/clib/mylib.h new file mode 100644 index 000000000..82a2a2c78 --- /dev/null +++ b/clib/mylib.h @@ -0,0 +1,4 @@ + + +int myfunction(int a); + diff --git a/clib/mylib.h.gch b/clib/mylib.h.gch new file mode 100644 index 000000000..835396736 Binary files /dev/null and b/clib/mylib.h.gch differ diff --git a/clib/mylib.o b/clib/mylib.o new file mode 100644 index 000000000..562a30d74 Binary files /dev/null and b/clib/mylib.o differ diff --git a/clib/test.chpl b/clib/test.chpl new file mode 100644 index 000000000..ba677b621 --- /dev/null +++ b/clib/test.chpl @@ -0,0 +1,10 @@ +// require "mylib.h", "mylib.c"; + + +extern proc myfunction(x: int): int; + + + +writeln("Hello, world!"); + +writeln(myfunction(5)); \ No newline at end of file diff --git a/cmake/LibTorchDL.cmake b/cmake/LibTorchDL.cmake new file mode 100644 index 000000000..0afd512a1 --- /dev/null +++ b/cmake/LibTorchDL.cmake @@ -0,0 +1,115 @@ +cmake_minimum_required(VERSION 3.31 FATAL_ERROR) + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") + +include(dlcache) + +include(CMakePrintHelpers) + + +# set(TORCH_COMPUTE_PLATFORM "cpu") # cu118, cu124, cu126, cpu +# set(TORCH_VERSION "2.1.0") +set(TORCH_URL_PREFIX "https://download.pytorch.org/libtorch/nightly/cpu") + + + + +if(UNIX AND NOT APPLE) + set(LINUX TRUE) +elseif(WIN32) + message(FATAL_ERROR "Windows is not supported yet.") +endif() + +if(APPLE) + set(TORCH_DISTRIBUTION "${TORCH_URL_PREFIX}/libtorch-macos-arm64-latest.zip") +elseif(LINUX) + set(TORCH_DISTRIBUTION "$${TORCH_URL_PREFIX}/libtorch-shared-with-deps-latest.zip") +endif() + +function(download_libtorch) + cmake_parse_arguments( + DL_TORCH + "CLEAR_CACHE" + "CACHE_DIR" + "DESTINATION" + ${ARGV} + ) + + cmake_print_variables(DL_TORCH_CLEAR_CACHE) + cmake_print_variables(DL_TORCH_CACHE_DIR) + cmake_print_variables(DL_TORCH_DESTINATION) + + + + if(DL_TORCH_CACHE_DIR) + set(TORCH_CACHE_DIR ${DL_TORCH_CACHE_DIR}) + else() + set(TORCH_CACHE_DIR "${CMAKE_SOURCE_DIR}/.cache") + endif() + + set(TORCH_CACHE_NAME "libtorch_cache.zip") + set(TORCH_CACHE "${TORCH_CACHE_DIR}/${TORCH_CACHE_NAME}") + # set(TORCH_DIR "${TORCH_CACHE_DIR}/libtorch") + + + if(DL_TORCH_DESTINATION) + set(TORCH_DIR ${DL_TORCH_DESTINATION}) + else() + set(TORCH_DIR "${TORCH_CACHE_DIR}/torchlib") + endif() + + if(EXISTS ${TORCH_CACHE}) + if(DL_TORCH_CLEAR_CACHE) + message(STATUS "Clearing cache: ${TORCH_CACHE}") + file(REMOVE "${TORCH_CACHE}") + set(SHOULD_DOWNLOAD TRUE) + else() + message(STATUS "Cache exists, skipping download.") + set(SHOULD_DOWNLOAD FALSE) + endif() + else() + message(STATUS "Cache does not exist, downloading.") + set(SHOULD_DOWNLOAD TRUE) + message(STATUS "Creating cache directory: ${TORCH_CACHE_DIR}") + file(MAKE_DIRECTORY "${TORCH_CACHE_DIR}") + endif() + + if(SHOULD_DOWNLOAD) + message(STATUS "Downloading from ${TORCH_DISTRIBUTION}") + file(DOWNLOAD "${TORCH_DISTRIBUTION}" "${TORCH_CACHE}" STATUS dlstatus) + list(GET dlstatus 0 status_code) + if(status_code) + message(FATAL_ERROR "${dlstatus} (${url})") + endif() + message(STATUS "Downloaded ${TORCH_DISTRIBUTION} to ${TORCH_CACHE}") + + if(EXISTS ${TORCH_DIR}) + message(STATUS "Removing existing directory: ${TORCH_DIR}") + file(REMOVE_RECURSE "${TORCH_DIR}") + file(MAKE_DIRECTORY "${TORCH_DIR}") + endif() + message(STATUS "Unpacking ${TORCH_CACHE} to ${TORCH_DIR}") + + cmake_print_variables(TORCH_DIR) + + file(MAKE_DIRECTORY "${TORCH_CACHE_DIR}/tmp") + file(ARCHIVE_EXTRACT + INPUT ${TORCH_CACHE} + DESTINATION "${TORCH_CACHE_DIR}/tmp" + ) + file(RENAME "${TORCH_CACHE_DIR}/tmp/libtorch" "${TORCH_DIR}") + + if(NOT EXISTS "${TORCH_CACHE_DIR}/tmp") + message(FATAL_ERROR "Failed to extract ${TORCH_CACHE} to ${TORCH_DIR}") + else() + message(STATUS "Extracted ${TORCH_CACHE} to ${TORCH_DIR}") + file(REMOVE_RECURSE "${TORCH_CACHE_DIR}/tmp") + endif() + + endif() + +endfunction() + +# dlcache("${TORCH_DISTRIBUTION}" OUT url) + +# message(STATUS "file loc >>>>> ${url}") \ No newline at end of file diff --git a/cmake/chapel/CMakeCHPLCompiler.cmake.in b/cmake/chapel/CMakeCHPLCompiler.cmake.in new file mode 100644 index 000000000..cc000ad9e --- /dev/null +++ b/cmake/chapel/CMakeCHPLCompiler.cmake.in @@ -0,0 +1,22 @@ +# Copyright 2023-2025 Hewlett Packard Enterprise Development LP +# Other additional copyright holders may be indicated within. +# +# The entirety of this work is licensed under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(CMAKE_CHPL_COMPILER "@CMAKE_CHPL_COMPILER@") +set(CMAKE_CHPL_COMPILER_LOADED 1) +set(CMAKE_CHPL_SOURCE_FILE_EXTENSIONS "@CMAKE_CHPL_SOURCE_FILE_EXTENSIONS@") +set(CMAKE_CHPL_OUTPUT_EXTENSION "@CMAKE_CHPL_OUTPUT_EXTENSION@") +set(CMAKE_CHPL_COMPILER_ENV_VAR "@CMAKE_CHPL_COMPILER_ENV_VAR@") diff --git a/cmake/chapel/CMakeCHPLInformation.cmake b/cmake/chapel/CMakeCHPLInformation.cmake new file mode 100644 index 000000000..2448ff1f5 --- /dev/null +++ b/cmake/chapel/CMakeCHPLInformation.cmake @@ -0,0 +1,32 @@ +# Copyright 2023-2025 Hewlett Packard Enterprise Development LP +# Other additional copyright holders may be indicated within. +# +# The entirety of this work is licensed under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# TODO: this is a hack, how do we tell cmake that we can't compile to object files? +set(CMAKE_CHPL_COMPILE_OBJECT "test -f || ln -s ") +set(CMAKE_CHPL_LINK_EXECUTABLE " -o ") +# doesn't work on link step + +# TODO: support --library directly to build Chapel shared libs for interoperability + +set(CMAKE_CHPL_SOURCE_FILE_EXTENSIONS chpl) + +set(CMAKE_CHPL_OUTPUT_EXTENSION ".chpl") + + +set(CMAKE_CHPL_FLAGS_RELEASE "--fast") +set(CMAKE_CHPL_FLAGS_DEBUG "-g") diff --git a/cmake/chapel/CMakeDetermineCHPLCompiler.cmake b/cmake/chapel/CMakeDetermineCHPLCompiler.cmake new file mode 100644 index 000000000..85e59b346 --- /dev/null +++ b/cmake/chapel/CMakeDetermineCHPLCompiler.cmake @@ -0,0 +1,46 @@ +# Copyright 2023-2025 Hewlett Packard Enterprise Development LP +# Other additional copyright holders may be indicated within. +# +# The entirety of this work is licensed under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# if there is an env CHPL_HOME, use it to find printchplenv +if (DEFINED ENV{CHPL_HOME}) + set(CHPL_HOME $ENV{CHPL_HOME}) + + execute_process( + COMMAND ${CHPL_HOME}/util/printchplenv --value --only CHPL_HOST_BIN_SUBDIR + OUTPUT_VARIABLE CHPL_HOST_BIN_SUBDIR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + set(CHPL_HOME_BIN_PATH ${CHPL_HOME}/bin/${CHPL_HOST_BIN_SUBDIR}) + # TODO: what if its a prefix install? +else() + set(CHPL_HOME "") + set(CHPL_HOME_BIN_PATH "") +endif() + +find_program( + CMAKE_CHPL_COMPILER + NAMES "chpl" + HINTS ${CHPL_HOME} ${CHPL_HOME_BIN_PATH} + DOC "chpl compiler" +) +# TODO: how to find chpl with just CHPL_HOME? + +set(CMAKE_CHPL_COMPILER_ENV_VAR "") + +configure_file(${CMAKE_CURRENT_LIST_DIR}/CMakeCHPLCompiler.cmake.in + ${CMAKE_PLATFORM_INFO_DIR}/CMakeCHPLCompiler.cmake) diff --git a/cmake/chapel/CMakeTestCHPLCompiler.cmake b/cmake/chapel/CMakeTestCHPLCompiler.cmake new file mode 100644 index 000000000..20cd8a372 --- /dev/null +++ b/cmake/chapel/CMakeTestCHPLCompiler.cmake @@ -0,0 +1,19 @@ +# Copyright 2023-2025 Hewlett Packard Enterprise Development LP +# Other additional copyright holders may be indicated within. +# +# The entirety of this work is licensed under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# For now do nothing +set(CMAKE_CHPL_COMPILER_WORKS 1 CACHE INTERNAL "") diff --git a/cmake/chapel/README.md b/cmake/chapel/README.md new file mode 100644 index 000000000..bb3cff024 --- /dev/null +++ b/cmake/chapel/README.md @@ -0,0 +1,17 @@ +# chpl CMake Support + +This directory contains the necessary files to support building Chapel programs using CMake. + +Take the following steps to use Chapel with CMake: + +1. Copy the files in this directory to your project's source directory. You may want to copy the files to a subdirectory like `cmake`, or you can just copy them to the root of your project. +2. Add `find_package(chpl REQUIRED HINTS .)` to your `CMakeLists.txt` file. + +Here is an example `CMakeLists.txt` file for a minimal Hello World program: + +```cmake +find_package(chpl REQUIRED HINTS .) +project(hello LANGUAGES CHPL) + +add_executable(hello hello.chpl) +``` diff --git a/cmake/chapel/chpl-config.cmake b/cmake/chapel/chpl-config.cmake new file mode 100644 index 000000000..145770e2a --- /dev/null +++ b/cmake/chapel/chpl-config.cmake @@ -0,0 +1,18 @@ +# Copyright 2023-2025 Hewlett Packard Enterprise Development LP +# Other additional copyright holders may be indicated within. +# +# The entirety of this work is licensed under the Apache License, +# Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. +# +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/cmake/dlcache.cmake b/cmake/dlcache.cmake new file mode 100644 index 000000000..49ffc781a --- /dev/null +++ b/cmake/dlcache.cmake @@ -0,0 +1,194 @@ + +cmake_minimum_required(VERSION 3.19) + + + +# dlcache("https://github.com/g-truc/glm/archive/refs/heads/master.zip" +# SHA256 97198B71B24AD5087114C1FB64DC3111AEE1C7976CB5AE8A7C4476F3EEAB8D69 +# OUT url +# ) +# message(STATUS "file loc >>>>> ${url}") + +function(gitcache url githash) + + if(WIN32) + file(TO_CMAKE_PATH $ENV{LocalAppData} appdatadir) + set(DLCACHEDIR "${appdatadir}/dlcache") + else() + set(DLCACHEDIR "$ENV{HOME}/.cache/dlcache") + endif() + string(REGEX REPLACE [^A-Za-z0-9/.-] _ urlstripped "${url}") + set(dlpath "${DLCACHEDIR}/${urlstripped}") + + set(TMPDEST "${dlpath}.tmp") + if(EXISTS "${TMPDEST}") + file(REMOVE_RECURSE "${TMPDEST}") + endif() + + if(NOT EXISTS "${dlpath}") + execute_process( + COMMAND git clone --recursive "${url}" "${TMPDEST}" + COMMAND_ERROR_IS_FATAL ANY + ) + execute_process( + COMMAND ${CMAKE_COMMAND} -E rename "${TMPDEST}" "${dlpath}" + COMMAND_ERROR_IS_FATAL ANY + ) + endif() + + set(FOUND 0) + if(EXISTS "${dlpath}") + execute_process( + COMMAND git show --format="%H" --no-patch + WORKING_DIRECTORY "${dlpath}" + OUTPUT_VARIABLE lout + ) + if(lout MATCHES "${githash}") + set(FOUND 1) + endif() + endif() + + if(NOT FOUND) + execute_process( + COMMAND ${CMAKE_COMMAND} -E rename "${dlpath}" "${TMPDEST}" + COMMAND_ERROR_IS_FATAL ANY + ) + execute_process( + COMMAND git clean -fdx + WORKING_DIRECTORY "${TMPDEST}" + COMMAND_ERROR_IS_FATAL ANY + ) + execute_process( + COMMAND git checkout --recurse-submodules -f "${githash}" + WORKING_DIRECTORY "${TMPDEST}" + COMMAND_ERROR_IS_FATAL ANY + ) + execute_process( + COMMAND ${CMAKE_COMMAND} -E rename "${TMPDEST}" "${dlpath}" + COMMAND_ERROR_IS_FATAL ANY + ) + endif() + + set(dl_local_path "${dlpath}" PARENT_SCOPE) +endfunction() + +macro(ghgitcache urlpart githash) + gitcache("https://github.com/${urlpart}.git" ${githash}) +endmacro() + +# dlcache("https://..." [SHA256 0123...] [OUT localFileLocVar] [UNPACK ] [UNPACK_OUT unpackDirLocVar]) +function(dlcache url) + # https://cmake.org/cmake/help/latest/command/cmake_parse_arguments.html + cmake_parse_arguments(DL "" "SHA256;OUT;UNPACK;UNPACK_OUT" "" ${ARGN} ) + + if(WIN32) + file(TO_CMAKE_PATH $ENV{LocalAppData} appdatadir) + set(DLCACHEDIR "${appdatadir}/dlcache") + else() + set(DLCACHEDIR "$ENV{HOME}/.cache/dlcache") + endif() + string(REGEX REPLACE [^A-Za-z0-9/.-] _ urlstripped "${url}") + set(dlpath "${DLCACHEDIR}/${urlstripped}") + + IF(EXISTS "${dlpath}") + ELSE() + IF(DL_SHA256) + file(DOWNLOAD "${url}" "${dlpath}" STATUS dlstatus) + ELSE() + file(DOWNLOAD "${url}" "${dlpath}" STATUS dlstatus) + ENDIF() + LIST(GET dlstatus 0 status_code) + IF(status_code) + MESSAGE(FATAL_ERROR "${dlstatus} (${url})") + ENDIF() + ENDIF() + + IF(DL_SHA256) + STRING(TOLOWER ${DL_SHA256} DL_SHA256) + FILE(SHA256 "${dlpath}" cksum) + STRING(TOLOWER ${cksum} cksum) + IF(cksum STREQUAL "${DL_SHA256}") + ELSE() + FILE(REMOVE "${dlpath}") + MESSAGE(FATAL_ERROR "CHECKSUM MISMATCH for: ${url}\nEXPECTED: ${DL_SHA256}\nGOT: ${cksum}") + ENDIF() + ENDIF() + + IF(DL_OUT) + set(${DL_OUT} "${dlpath}" PARENT_SCOPE) + ENDIF() + + IF(DL_UNPACK) + cmake_path(SET unpack_path NORMALIZE "${CMAKE_CURRENT_BINARY_DIR}/${DL_UNPACK}") + message("unpack path = ${unpack_path}") + IF(NOT EXISTS ${unpack_path}) + execute_process( + COMMAND ${CMAKE_COMMAND} -E make_directory "${unpack_path}" + ) + execute_process( + COMMAND ${CMAKE_COMMAND} -E tar x "${dlpath}" + WORKING_DIRECTORY ${unpack_path} + ) + ENDIF() + IF(DL_UNPACK_OUT) + set(${DL_UNPACK_OUT} "${unpack_path}" PARENT_SCOPE) + ENDIF() + ENDIF() +endfunction() + + +macro(dlcache2 url sha256) + dlcache("${url}" SHA256 "${sha256}" OUT "dl_local_path") +endmacro() + +# fetch source code zip from github +# +# ${dl_local_path} will contain the file path +# +# project: github-user/project-name +# tag: either 40 chars (commit id) or a ref tag +macro(dlghzip project tag sha256) + string(LENGTH "${tag}" taglen) + if(taglen EQUAL 40) + dlcache("https://github.com/${project}/archive/${tag}.zip" SHA256 "${sha256}" OUT "dl_local_path") + else() + dlcache("https://github.com/${project}/archive/refs/tags/${tag}.zip" SHA256 "${sha256}" OUT "dl_local_path") + endif() +endmacro() + + +# Examples: +# +# dlcache_assets( +# LIST +# https://raw.githubusercontent.com/Overv/VulkanTutorial/master/images/texture.jpg +# 663a43377a9d3b42a1925a17313b12e339b146d219a62c4c07a56c89032858bb +# https://raw.githubusercontent.com/Overv/VulkanTutorial/master/resources/viking_room.png +# facb693858cafcb70b7eed264e34107f06bbf3f41805e7b8084e5b42bd914a66 +# OUTDIR textures +# ) +# dlcache_assets( +# LIST +# https://raw.githubusercontent.com/Overv/VulkanTutorial/master/resources/viking_room.obj +# 0af27cd99ce43f48c89d9c73cff47cbdfc3d29c3754b29bd0ccfe7e3fe7de869 +# OUTDIR models +# ) +# +# Writes the given files into textures/modles directories, using the last part of each url as filename. +# +function(dlcache_assets) + cmake_parse_arguments(DL "EXTRACT_FILENAMES" "OUTDIR" "LIST" ${ARGN}) + if(NOT DL_OUTDIR) + set(DL_OUTDIR "assets") + endif() + list(LENGTH DL_LIST len1) + math(EXPR len2 "${len1} / 2 - 1") + foreach(val RANGE ${len2}) + math(EXPR vala "2 * ${val}") + math(EXPR valb "2 * ${val} + 1") + list(GET DL_LIST ${vala} val1) + list(GET DL_LIST ${valb} val2) + dlcache2("${val1}" "${val2}") + file(COPY "${dl_local_path}" DESTINATION "${DL_OUTDIR}") + endforeach() +endfunction() \ No newline at end of file diff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt new file mode 100644 index 000000000..4590c7216 --- /dev/null +++ b/dependencies/CMakeLists.txt @@ -0,0 +1,89 @@ +cmake_minimum_required(VERSION 3.18) +project(MyProject LANGUAGES CXX) + +# For ExternalProject_Add +include(FetchContent) +include(ExternalProject) + +# ------------------------------------------------------------------------------ +# 1) External project: build PyTorch (libtorch) from source as STATIC +# ------------------------------------------------------------------------------ + +# Where to place PyTorch after installation +set(PYTORCH_INSTALL_DIR "${CMAKE_BINARY_DIR}/pytorch-install") + +# ExternalProject_Add can fetch from Git, a local path, or a release tarball. +# Here, for simplicity, we'll fetch from Git. In practice, you might want +# a fixed commit or a release tarball for reproducible builds. + +ExternalProject_Add( + pytorch + GIT_REPOSITORY https://github.com/pytorch/pytorch.git + GIT_TAG v2.0.1 # Example: specify a particular release + UPDATE_COMMAND "" # Don’t auto-run 'git pull' + PATCH_COMMAND "" # No custom patch step + + # We need all PyTorch submodules. By default, ExternalProject won't do submodule init. + # So we can do that in a separate step if we want a full build. For a minimal CPU build, + # you might not need them all, but let's be safe: + STEP_TARGETS clone + # After 'clone', run "git submodule update --init --recursive" + # to fetch all submodules. + # We can use a little trick with COMMAND. + PATCH_COMMAND "git submodule update --init --recursive" + + CMAKE_ARGS + -DBUILD_SHARED_LIBS=OFF # Build static libraries + -DBUILD_PYTHON=OFF # Don’t build Python bindings + -DBUILD_TEST=OFF # Don’t build tests + -DUSE_CUDA=OFF # Disable CUDA + -DUSE_CUDNN=OFF # Disable cuDNN + -DUSE_MKLDNN=OFF # Disable MKLDNN for simplicity + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX=${PYTORCH_INSTALL_DIR} + + INSTALL_DIR ${PYTORCH_INSTALL_DIR} # Where to install +) + +# ------------------------------------------------------------------------------ +# 2) Create an INTERFACE library to wrap the installed static libs +# ------------------------------------------------------------------------------ + +# We'll create a dummy target that depends on 'pytorch' so that +# building your own code will first build/install PyTorch. + +add_library(torch_interface INTERFACE) + +# Ensure that our 'torch_interface' target isn't used until PyTorch is built +add_dependencies(torch_interface pytorch) + +# Include directories for PyTorch +target_include_directories(torch_interface INTERFACE + "${PYTORCH_INSTALL_DIR}/include" + "${PYTORCH_INSTALL_DIR}/include/torch/csrc/api/include" +) + +# Link the relevant static libraries. For a minimal CPU-only build, +# you'll likely need at least these (names can vary by version). +# The exact set can differ depending on which components got built. + +target_link_libraries(torch_interface INTERFACE + "${PYTORCH_INSTALL_DIR}/lib/libtorch.a" + "${PYTORCH_INSTALL_DIR}/lib/libtorch_cpu.a" + "${PYTORCH_INSTALL_DIR}/lib/libc10.a" + + # System libraries often needed: + pthread + dl + rt +) + +# ------------------------------------------------------------------------------ +# 3) Build your own executable that uses torch_interface +# ------------------------------------------------------------------------------ + +# add_executable(my_app src/main.cpp) + +# # Link your app against our interface library +# target_link_libraries(my_app PRIVATE torch_interface) + diff --git a/dependencies/run.sh b/dependencies/run.sh new file mode 100644 index 000000000..3abffc955 --- /dev/null +++ b/dependencies/run.sh @@ -0,0 +1,3 @@ + +cmake -S . -B build +cmake --build build diff --git a/embed_libtorch.sh b/embed_libtorch.sh new file mode 100755 index 000000000..c3d46fdc6 --- /dev/null +++ b/embed_libtorch.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env sh + +# +# This script prints the flags required by the Chapel compiler to embed Python +# code in a Chapel program. It is intended to be used by consumers of the +# 'Python' module. See https://chapel-lang.org/docs/modules/packages/Python.html +# + +# get the chpl home directory +# chpl_home=$(cd $(dirname $0) ; cd ..; cd ..; pwd) +# chpl_python=$("$chpl_home/util/config/find-python.sh") + +cd "$(dirname "$0")" + +mkdir -p build +cd build +cmake .. > /dev/null +make -j4 > /dev/null +cd .. + +SOURCE_DIR=$(pwd) +BRIDGE_LIB=$SOURCE_DIR/build/CMakeFiles/bridge.dir/bridge/lib/bridge.cpp.o +LIBTORCH_DIR=$SOURCE_DIR/libtorch + + +echo "-M $SOURCE_DIR/lib $SOURCE_DIR/bridge/include/bridge.h $BRIDGE_LIB -I $SOURCE_DIR/bridge/include -L $LIBTORCH_DIR/lib --ldflags -Wl,-rpath,$SOURCE_DIR/libtorch/lib" + +# PYTHON_INCLUDE_DIR=$($chpl_python -c "import sysconfig; print(sysconfig.get_paths()['include'])") +# PYTHON_LIB_DIR=$($chpl_python -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))") +# PYTHON_LDVERSION=$($chpl_python -c "import sysconfig; print(sysconfig.get_config_var('LDVERSION'))") + +# DISABLE_WARNINGS="" +# # some older python's don't use `#ifndef` when they should +# # so we disable redefinition warnings for clean testing +# DISABLE_WARNINGS="$DISABLE_WARNINGS --ccflags -Wno-macro-redefined" + +# echo "--ccflags -isystem$PYTHON_INCLUDE_DIR -L$PYTHON_LIB_DIR --ldflags -Wl,-rpath,$PYTHON_LIB_DIR -lpython$PYTHON_LDVERSION $DISABLE_WARNINGS" \ No newline at end of file diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 000000000..361a58c0e --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,5 @@ + + +add_subdirectory(my_example) + +add_subdirectory(torch_model_loading) diff --git a/examples/my_example/CMakeLists.txt b/examples/my_example/CMakeLists.txt new file mode 100644 index 000000000..b197b0d65 --- /dev/null +++ b/examples/my_example/CMakeLists.txt @@ -0,0 +1,20 @@ + + +add_executable(MyExample + ${PROJECT_ROOT_DIR}/examples/my_example/my_example.chpl + ${CHAI_LIB_FILES} +) +add_dependencies(MyExample bridge) +add_dependencies(MyExample ChAI) +target_link_options(MyExample + PRIVATE + ${CHAI_LINKER_ARGS} +) + + +# add_custom_command(TARGET MyMyExampleApp POST_BUILD +# COMMAND ${CMAKE_COMMAND} -E copy_directory +# "${CMAKE_CURRENT_SOURCE_DIR}/resources" +# "$/resources" +# COMMENT "Copying runtime resources" +# ) \ No newline at end of file diff --git a/examples/my_example/my_example.chpl b/examples/my_example/my_example.chpl new file mode 100644 index 000000000..a3585b0dd --- /dev/null +++ b/examples/my_example/my_example.chpl @@ -0,0 +1,7 @@ +use Tensor; + + +proc main() { + var a = ndarray.arange(1, 10); + writeln("a: ", a); +} \ No newline at end of file diff --git a/examples/torch_model_loading/CMakeLists.txt b/examples/torch_model_loading/CMakeLists.txt new file mode 100644 index 000000000..b8cd059cd --- /dev/null +++ b/examples/torch_model_loading/CMakeLists.txt @@ -0,0 +1,22 @@ + + + + + +add_executable(TorchLoad + ${CMAKE_CURRENT_SOURCE_DIR}/torch_load.chpl + ${CHAI_LIB_FILES} +) +add_dependencies(TorchLoad bridge) +add_dependencies(TorchLoad ChAI) +target_link_options(TorchLoad + PRIVATE + ${CHAI_LINKER_ARGS} +) + +add_custom_command(TARGET TorchLoad POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + "${CMAKE_CURRENT_SOURCE_DIR}/models" + "$/models" + COMMENT "Copying model folder" +) \ No newline at end of file diff --git a/examples/torch_model_loading/mktensor.ipynb b/examples/torch_model_loading/mktensor.ipynb new file mode 100644 index 000000000..81763c1fd --- /dev/null +++ b/examples/torch_model_loading/mktensor.ipynb @@ -0,0 +1,143 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "873dd3b8", + "metadata": {}, + "outputs": [], + "source": [ + "import torch" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "a07c23ff", + "metadata": {}, + "outputs": [], + "source": [ + "def find_factors(num):\n", + " \"\"\"\n", + " Finds all factors of a given number.\n", + "\n", + " Args:\n", + " num: An integer.\n", + "\n", + " Returns:\n", + " A list of integers representing the factors of num.\n", + " \"\"\"\n", + " factors = []\n", + " for i in range(1, num + 1):\n", + " if num % i == 0:\n", + " factors.append(i)\n", + " return factors" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "131adc46", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "f1: 10000, f2: 5\n" + ] + } + ], + "source": [ + "num_elt = 50000\n", + "f1 = find_factors(num_elt)[-4]\n", + "f2 = num_elt // f1\n", + "print(f\"f1: {f1}, f2: {f2}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "d4aed442", + "metadata": {}, + "outputs": [], + "source": [ + "x = torch.arange(0,num_elt)\n", + "x = x.reshape(f1,f2).to(torch.float32)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "481d4709", + "metadata": {}, + "outputs": [], + "source": [ + "torch.save(x, 'models/my_tensor.pt')" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "1a17ec15", + "metadata": {}, + "outputs": [], + "source": [ + "m = {'a': x, 'b': x + 1}\n", + "torch.save(m, 'models/my_tensor_dict.pt')" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "841d4dfe", + "metadata": {}, + "outputs": [], + "source": [ + "class MyModule(torch.nn.Module):\n", + " def __init__(self):\n", + " super(MyModule, self).__init__()\n", + " self.conv1 = torch.nn.Conv2d(in_channels=3,\n", + " out_channels=16,\n", + " kernel_size=3,\n", + " stride=2)\n", + " self.conv2 = torch.nn.Conv2d(in_channels=16,\n", + " out_channels=32,\n", + " kernel_size=3,\n", + " stride=2)\n", + "\n", + " def forward(self, x):\n", + " return self.linear(x)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ca34dafc", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/torch_model_loading/models/my_tensor.pt b/examples/torch_model_loading/models/my_tensor.pt new file mode 100644 index 000000000..768a801f4 Binary files /dev/null and b/examples/torch_model_loading/models/my_tensor.pt differ diff --git a/examples/torch_model_loading/models/my_tensor_dict.pt b/examples/torch_model_loading/models/my_tensor_dict.pt new file mode 100644 index 000000000..054c9fb55 Binary files /dev/null and b/examples/torch_model_loading/models/my_tensor_dict.pt differ diff --git a/examples/torch_model_loading/torch_load.chpl b/examples/torch_model_loading/torch_load.chpl new file mode 100644 index 000000000..c0e5e1be7 --- /dev/null +++ b/examples/torch_model_loading/torch_load.chpl @@ -0,0 +1,15 @@ +use Tensor; + + +proc main(args: [] string) { + // const a = ndarray.loadPyTorchTensorDictWithKey(2,"models/my_tensor_dict.pt","a"); + // const b = ndarray.loadPyTorchTensorDictWithKey(2,"models/my_tensor_dict.pt","b"); + // writeln("a sum: ", a.sum()); + // writeln("b sum: ", b.sum()); + + var image = ndarray.loadFrom(args[1],3,real(32)); + writeln("Loaded image: ", args[1]); + writeln("Image shape: ", image.shape); + + image.saveImage("test.jpg"); +} \ No newline at end of file diff --git a/examples/vgg/README.md b/examples/vgg/README.md index 2e356e57d..de28fb5a6 100644 --- a/examples/vgg/README.md +++ b/examples/vgg/README.md @@ -20,3 +20,7 @@ Run `python3 test.py ` to run the model in python. The output wil #### Compare with `python3 run_vgg.py imgs/frog.jpg` and `./vgg imgs/frog.chdata` + +```bash +$ chpl --fast -o vgg test.chpl -M ../../lib /Users/iainmoncrief/Documents/Github/ChAI/bridge/include/bridge.h /Users/iainmoncrief/Documents/Github/ChAI/build/CMakeFiles/bridge.dir/bridge/lib/bridge.cpp.o -L /Users/iainmoncrief/Documents/Github/ChAI/libtorch/lib -ltorch -ltorch_cpu -lc10 -ltorch_global_deps --ldflags "-Wl,-rpath,/Users/iainmoncrief/Documents/Github/ChAI/libtorch/lib" +``` \ No newline at end of file diff --git a/examples/vgg/dump_weights.py b/examples/vgg/dump_weights.py index 0c3b57103..b2a5e310c 100644 --- a/examples/vgg/dump_weights.py +++ b/examples/vgg/dump_weights.py @@ -3,6 +3,8 @@ import sys import os +import vgg + from vgg import vgg16 @@ -18,5 +20,55 @@ os.makedirs('models/vgg16', exist_ok=True) model.chai_dump('models/vgg16','vgg16', with_json=False, verbose=True) -# print(model.state_dict().keys()) -# print([(n,w.dtype) for (n,w) in model.state_dict().items()]) +# # print(model.state_dict().keys()) +# # print([(n,w.dtype) for (n,w) in model.state_dict().items()]) + + +for vggxx in vgg.model_urls.keys(): + print(vggxx) + model = vgg.__dict__[vggxx](pretrained=True) + model = model.to(torch.float16) + model.eval() + + # # Add the scripts directory to the sys.path + + # sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'scripts'))) + + # import chai + + # os.makedirs('models/vgg16', exist_ok=True) + # model.chai_dump('models/vgg16',vggxx, with_json=False, verbose=True) + + # print(f'models/traced_{vggxx}.pt') + # faux_input = torch.randn(3,720,1280) + # traced_model = torch.jit.trace(model, faux_input) + # traced_model.save(f'models/traced_{vggxx}.pt') + + # print(f'models/{vggxx}.pt') + # sd = model.state_dict() + # torch.save(sd, f'models/{vggxx}.pt') + + # # print(f'models/traced_{vggxx}.pt') + # # faux_input = torch.randn(3,720,1280).to(torch.float16) + # # traced_model = torch.jit.trace(model, faux_input) + # # torch.save(traced_model,f'models/traced_{vggxx}.pt') + + # print(f'models/script_{vggxx}.pt') + # script_model = torch.jit.script(model) + # script_model.save(f'models/script_{vggxx}.pt') + + # test = torch.rand(1,3,720,1280).to(torch.float32) + # print(model(test).shape) + + model.eval() + print(f'models/trace_{vggxx}.pt') + faux_input = torch.rand(1,3,720,1280).to(torch.float16) + print(model(faux_input).shape) + trace_model = torch.jit.trace(model,faux_input) + trace_model.save(f'models/trace_{vggxx}.pt') + # torch.save(trace_model,f'models/trace_{vggxx}.pt') + + + # print(model.state_dict().keys()) + # print([(n,w.dtype) for (n,w) in model.state_dict().items()]) + \ No newline at end of file diff --git a/examples/vgg/imgs/broccoli.jpg b/examples/vgg/images/broccoli.jpg similarity index 100% rename from examples/vgg/imgs/broccoli.jpg rename to examples/vgg/images/broccoli.jpg diff --git a/examples/vgg/imgs/broccoli.json b/examples/vgg/images/broccoli.json similarity index 100% rename from examples/vgg/imgs/broccoli.json rename to examples/vgg/images/broccoli.json diff --git a/examples/vgg/imgs/broccoli.meta.json b/examples/vgg/images/broccoli.meta.json similarity index 100% rename from examples/vgg/imgs/broccoli.meta.json rename to examples/vgg/images/broccoli.meta.json diff --git a/examples/vgg/imgs/broccoli.npy b/examples/vgg/images/broccoli.npy similarity index 100% rename from examples/vgg/imgs/broccoli.npy rename to examples/vgg/images/broccoli.npy diff --git a/examples/vgg/imgs/broccoli2.jpg b/examples/vgg/images/broccoli2.jpg similarity index 100% rename from examples/vgg/imgs/broccoli2.jpg rename to examples/vgg/images/broccoli2.jpg diff --git a/examples/vgg/imgs/broccoli2.json b/examples/vgg/images/broccoli2.json similarity index 100% rename from examples/vgg/imgs/broccoli2.json rename to examples/vgg/images/broccoli2.json diff --git a/examples/vgg/imgs/broccoli2.meta.json b/examples/vgg/images/broccoli2.meta.json similarity index 100% rename from examples/vgg/imgs/broccoli2.meta.json rename to examples/vgg/images/broccoli2.meta.json diff --git a/examples/vgg/imgs/broccoli2.npy b/examples/vgg/images/broccoli2.npy similarity index 100% rename from examples/vgg/imgs/broccoli2.npy rename to examples/vgg/images/broccoli2.npy diff --git a/examples/vgg/imgs/dog.jpg b/examples/vgg/images/dog.jpg similarity index 100% rename from examples/vgg/imgs/dog.jpg rename to examples/vgg/images/dog.jpg diff --git a/examples/vgg/imgs/dog.json b/examples/vgg/images/dog.json similarity index 100% rename from examples/vgg/imgs/dog.json rename to examples/vgg/images/dog.json diff --git a/examples/vgg/imgs/dog.meta.json b/examples/vgg/images/dog.meta.json similarity index 100% rename from examples/vgg/imgs/dog.meta.json rename to examples/vgg/images/dog.meta.json diff --git a/examples/vgg/imgs/dog.npy b/examples/vgg/images/dog.npy similarity index 100% rename from examples/vgg/imgs/dog.npy rename to examples/vgg/images/dog.npy diff --git a/examples/vgg/imgs/frog.jpg b/examples/vgg/images/frog.jpg similarity index 100% rename from examples/vgg/imgs/frog.jpg rename to examples/vgg/images/frog.jpg diff --git a/examples/vgg/imgs/frog.json b/examples/vgg/images/frog.json similarity index 100% rename from examples/vgg/imgs/frog.json rename to examples/vgg/images/frog.json diff --git a/examples/vgg/imgs/frog.meta.json b/examples/vgg/images/frog.meta.json similarity index 100% rename from examples/vgg/imgs/frog.meta.json rename to examples/vgg/images/frog.meta.json diff --git a/examples/vgg/imgs/frog.npy b/examples/vgg/images/frog.npy similarity index 100% rename from examples/vgg/imgs/frog.npy rename to examples/vgg/images/frog.npy diff --git a/examples/vgg/imgs/hotdog.jpg b/examples/vgg/images/hotdog.jpg similarity index 100% rename from examples/vgg/imgs/hotdog.jpg rename to examples/vgg/images/hotdog.jpg diff --git a/examples/vgg/imgs/hotdog.json b/examples/vgg/images/hotdog.json similarity index 100% rename from examples/vgg/imgs/hotdog.json rename to examples/vgg/images/hotdog.json diff --git a/examples/vgg/imgs/hotdog.meta.json b/examples/vgg/images/hotdog.meta.json similarity index 100% rename from examples/vgg/imgs/hotdog.meta.json rename to examples/vgg/images/hotdog.meta.json diff --git a/examples/vgg/imgs/hotdog.npy b/examples/vgg/images/hotdog.npy similarity index 100% rename from examples/vgg/imgs/hotdog.npy rename to examples/vgg/images/hotdog.npy diff --git a/examples/vgg/images/my_tensor.pt b/examples/vgg/images/my_tensor.pt new file mode 100644 index 000000000..8b43ecb80 Binary files /dev/null and b/examples/vgg/images/my_tensor.pt differ diff --git a/examples/vgg/imgs/frog.chdata b/examples/vgg/imgs/frog.chdata deleted file mode 100644 index a8051f83b..000000000 Binary files a/examples/vgg/imgs/frog.chdata and /dev/null differ diff --git a/examples/vgg/mktensor.ipynb b/examples/vgg/mktensor.ipynb new file mode 100644 index 000000000..e3f6e2b1e --- /dev/null +++ b/examples/vgg/mktensor.ipynb @@ -0,0 +1,135 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "873dd3b8", + "metadata": {}, + "outputs": [], + "source": [ + "import torch" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a07c23ff", + "metadata": {}, + "outputs": [], + "source": [ + "def find_factors(num):\n", + " \"\"\"\n", + " Finds all factors of a given number.\n", + "\n", + " Args:\n", + " num: An integer.\n", + "\n", + " Returns:\n", + " A list of integers representing the factors of num.\n", + " \"\"\"\n", + " factors = []\n", + " for i in range(1, num + 1):\n", + " if num % i == 0:\n", + " factors.append(i)\n", + " return factors" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "131adc46", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "f1: 10000, f2: 5\n" + ] + } + ], + "source": [ + "num_elt = 50000\n", + "f1 = find_factors(num_elt)[-4]\n", + "f2 = num_elt // f1\n", + "print(f\"f1: {f1}, f2: {f2}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "d4aed442", + "metadata": {}, + "outputs": [], + "source": [ + "x = torch.arange(0,num_elt)\n", + "x = x.reshape(f1,f2).to(torch.float32)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "481d4709", + "metadata": {}, + "outputs": [], + "source": [ + "torch.save(x, 'my_tensor.pt')" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "1a17ec15", + "metadata": {}, + "outputs": [], + "source": [ + "m = {'a': x, 'b': x + 1}\n", + "torch.save(m, 'my_tensor_dict.pt')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "841d4dfe", + "metadata": {}, + "outputs": [], + "source": [ + "class MyModule(torch.nn.Module):\n", + " def __init__(self):\n", + " super(MyModule, self).__init__()\n", + " self.conv1 = torch.nn.Conv2d(in_channels=3,\n", + " out_channels=16,\n", + " kernel_size=3,\n", + " stride=2)\n", + " self.conv2 = torch.nn.Conv2d(in_channels=16,\n", + " out_channels=32,\n", + " kernel_size=3,\n", + " stride=2)\n", + "\n", + " def forward(self, x):\n", + " return self.linear(x)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/vgg/models/vgg16/features.11.bias.meta.json b/examples/vgg/models/vgg16/features.11.bias.meta.json new file mode 100644 index 000000000..a540e4ef1 --- /dev/null +++ b/examples/vgg/models/vgg16/features.11.bias.meta.json @@ -0,0 +1,10 @@ +{ + "name": "features.11.bias", + "shape": [ + 512 + ], + "rank": 1, + "size": 512, + "dtype": "float32", + "element_bits": 32 +} \ No newline at end of file diff --git a/examples/vgg/models/vgg16/features.11.weight.meta.json b/examples/vgg/models/vgg16/features.11.weight.meta.json new file mode 100644 index 000000000..d83559fe9 --- /dev/null +++ b/examples/vgg/models/vgg16/features.11.weight.meta.json @@ -0,0 +1,13 @@ +{ + "name": "features.11.weight", + "shape": [ + 512, + 256, + 3, + 3 + ], + "rank": 4, + "size": 1179648, + "dtype": "float32", + "element_bits": 32 +} \ No newline at end of file diff --git a/examples/vgg/models/vgg16/features.13.bias.meta.json b/examples/vgg/models/vgg16/features.13.bias.meta.json new file mode 100644 index 000000000..200f052f8 --- /dev/null +++ b/examples/vgg/models/vgg16/features.13.bias.meta.json @@ -0,0 +1,10 @@ +{ + "name": "features.13.bias", + "shape": [ + 512 + ], + "rank": 1, + "size": 512, + "dtype": "float32", + "element_bits": 32 +} \ No newline at end of file diff --git a/examples/vgg/models/vgg16/features.13.weight.meta.json b/examples/vgg/models/vgg16/features.13.weight.meta.json new file mode 100644 index 000000000..653bf4bef --- /dev/null +++ b/examples/vgg/models/vgg16/features.13.weight.meta.json @@ -0,0 +1,13 @@ +{ + "name": "features.13.weight", + "shape": [ + 512, + 512, + 3, + 3 + ], + "rank": 4, + "size": 2359296, + "dtype": "float32", + "element_bits": 32 +} \ No newline at end of file diff --git a/examples/vgg/models/vgg16/features.16.bias.meta.json b/examples/vgg/models/vgg16/features.16.bias.meta.json new file mode 100644 index 000000000..0b3a35b40 --- /dev/null +++ b/examples/vgg/models/vgg16/features.16.bias.meta.json @@ -0,0 +1,10 @@ +{ + "name": "features.16.bias", + "shape": [ + 512 + ], + "rank": 1, + "size": 512, + "dtype": "float32", + "element_bits": 32 +} \ No newline at end of file diff --git a/examples/vgg/models/vgg16/features.16.weight.meta.json b/examples/vgg/models/vgg16/features.16.weight.meta.json new file mode 100644 index 000000000..7a87e17e4 --- /dev/null +++ b/examples/vgg/models/vgg16/features.16.weight.meta.json @@ -0,0 +1,13 @@ +{ + "name": "features.16.weight", + "shape": [ + 512, + 512, + 3, + 3 + ], + "rank": 4, + "size": 2359296, + "dtype": "float32", + "element_bits": 32 +} \ No newline at end of file diff --git a/examples/vgg/models/vgg16/features.18.bias.meta.json b/examples/vgg/models/vgg16/features.18.bias.meta.json new file mode 100644 index 000000000..d1e1f8220 --- /dev/null +++ b/examples/vgg/models/vgg16/features.18.bias.meta.json @@ -0,0 +1,10 @@ +{ + "name": "features.18.bias", + "shape": [ + 512 + ], + "rank": 1, + "size": 512, + "dtype": "float32", + "element_bits": 32 +} \ No newline at end of file diff --git a/examples/vgg/models/vgg16/features.18.weight.meta.json b/examples/vgg/models/vgg16/features.18.weight.meta.json new file mode 100644 index 000000000..dee9e06a6 --- /dev/null +++ b/examples/vgg/models/vgg16/features.18.weight.meta.json @@ -0,0 +1,13 @@ +{ + "name": "features.18.weight", + "shape": [ + 512, + 512, + 3, + 3 + ], + "rank": 4, + "size": 2359296, + "dtype": "float32", + "element_bits": 32 +} \ No newline at end of file diff --git a/examples/vgg/models/vgg16/features.3.bias.meta.json b/examples/vgg/models/vgg16/features.3.bias.meta.json new file mode 100644 index 000000000..c44ef860c --- /dev/null +++ b/examples/vgg/models/vgg16/features.3.bias.meta.json @@ -0,0 +1,10 @@ +{ + "name": "features.3.bias", + "shape": [ + 128 + ], + "rank": 1, + "size": 128, + "dtype": "float32", + "element_bits": 32 +} \ No newline at end of file diff --git a/examples/vgg/models/vgg16/features.3.weight.meta.json b/examples/vgg/models/vgg16/features.3.weight.meta.json new file mode 100644 index 000000000..f5b5a3ba1 --- /dev/null +++ b/examples/vgg/models/vgg16/features.3.weight.meta.json @@ -0,0 +1,13 @@ +{ + "name": "features.3.weight", + "shape": [ + 128, + 64, + 3, + 3 + ], + "rank": 4, + "size": 73728, + "dtype": "float32", + "element_bits": 32 +} \ No newline at end of file diff --git a/examples/vgg/models/vgg16/features.6.bias.meta.json b/examples/vgg/models/vgg16/features.6.bias.meta.json new file mode 100644 index 000000000..89901358c --- /dev/null +++ b/examples/vgg/models/vgg16/features.6.bias.meta.json @@ -0,0 +1,10 @@ +{ + "name": "features.6.bias", + "shape": [ + 256 + ], + "rank": 1, + "size": 256, + "dtype": "float32", + "element_bits": 32 +} \ No newline at end of file diff --git a/examples/vgg/models/vgg16/features.6.weight.meta.json b/examples/vgg/models/vgg16/features.6.weight.meta.json new file mode 100644 index 000000000..9b4479ffd --- /dev/null +++ b/examples/vgg/models/vgg16/features.6.weight.meta.json @@ -0,0 +1,13 @@ +{ + "name": "features.6.weight", + "shape": [ + 256, + 128, + 3, + 3 + ], + "rank": 4, + "size": 294912, + "dtype": "float32", + "element_bits": 32 +} \ No newline at end of file diff --git a/examples/vgg/models/vgg16/features.8.bias.meta.json b/examples/vgg/models/vgg16/features.8.bias.meta.json new file mode 100644 index 000000000..6a0a8a86a --- /dev/null +++ b/examples/vgg/models/vgg16/features.8.bias.meta.json @@ -0,0 +1,10 @@ +{ + "name": "features.8.bias", + "shape": [ + 256 + ], + "rank": 1, + "size": 256, + "dtype": "float32", + "element_bits": 32 +} \ No newline at end of file diff --git a/examples/vgg/models/vgg16/features.8.weight.meta.json b/examples/vgg/models/vgg16/features.8.weight.meta.json new file mode 100644 index 000000000..e0f2d8189 --- /dev/null +++ b/examples/vgg/models/vgg16/features.8.weight.meta.json @@ -0,0 +1,13 @@ +{ + "name": "features.8.weight", + "shape": [ + 256, + 256, + 3, + 3 + ], + "rank": 4, + "size": 589824, + "dtype": "float32", + "element_bits": 32 +} \ No newline at end of file diff --git a/examples/vgg/my_tensor.pt b/examples/vgg/my_tensor.pt new file mode 100644 index 000000000..768a801f4 Binary files /dev/null and b/examples/vgg/my_tensor.pt differ diff --git a/examples/vgg/old_vgg.chpl b/examples/vgg/old_vgg.chpl new file mode 100644 index 000000000..f84f24dd2 --- /dev/null +++ b/examples/vgg/old_vgg.chpl @@ -0,0 +1,67 @@ +use VGG; +use Tensor; + +config param vggExampleDir = "."; + +writeln("VGG Example Directory: ", vggExampleDir); + +config const k = 5; +config const modelDir = vggExampleDir + "/models/vgg16/"; +config const labelFile = vggExampleDir + "/imagenet/LOC_synset_mapping.txt"; + + +proc getLabels(): [] { + use IO; + const r = openReader(labelFile); + const lines = r.lines(stripNewline=true); + // for each line, split on space, take the second part + forall l in lines { + var splat = l.split(" ", maxsplit=1); + l = splat[1]; + } + return lines; +} + +proc confidence(x: []): [] { + use Math; + var expSum = + reduce exp(x); + const res = (exp(x) / expSum) * 100.0; + writeln("Input shape: ", x.shape); + writeln("Result rank: ", res.rank); + writeln("Result shape: ", res.shape); +return res; +} + +// returns (top k indicies, top k condiences) +proc run(model: borrowed, file: string) { + const img = Tensor.load(file):real(32); + const output = model(img); + + const top = output.topk(k); + var topArr = top.tensorize(1).array.data; + var percent = confidence(output.tensorize(1).array.data); + + var percentTopk = [i in 0.. mySize then util.err("Cannot get top ", k, " from ", mySize, " elements."); var topK: [0..