Skip to content

Commit

Permalink
Merge pull request #114 from yungyuc/feature/enable-metal-manager
Browse files Browse the repository at this point in the history
Add code to build with Apple Metal
  • Loading branch information
yungyuc committed Jul 31, 2022
2 parents 475a562 + 8bdb7a1 commit f376359
Show file tree
Hide file tree
Showing 19 changed files with 379 additions and 30 deletions.
13 changes: 6 additions & 7 deletions .github/workflows/modmesh_pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,15 @@ jobs:
echo "flake8 path: $(which flake8)"
echo "flake8 version: $(flake8 --version)"
- name: buildext
run: |
make buildext \
VERBOSE=1 BUILD_QT=OFF USE_CLANG_TIDY=OFF \
CMAKE_BUILD_TYPE=${{ matrix.cmake_build_type }} \
CMAKE_ARGS="-DPYTHON_EXECUTABLE=$(which python3)"
- name: pytest
run: |
MAKE_ARGS=""
if [ "${{ matrix.os }}" == "macos-12" ] ; then \
thirdparty/metal-cpp.sh ; \
MAKE_ARGS="${MAKE_ARGS} BUILD_METAL=ON" ; \
fi
make pytest \
${MAKE_ARGS} \
VERBOSE=1 BUILD_QT=OFF USE_CLANG_TIDY=ON \
CMAKE_BUILD_TYPE=${{ matrix.cmake_build_type }} \
CMAKE_ARGS="-DPYTHON_EXECUTABLE=$(which python3)"
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
__pycache__/
build/
dist/
thirdparty/install/
thirdparty/archive/
tmp/
setup.mk
*.egg-info/
Expand Down
15 changes: 13 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ if(NOT SKIP_PYTHON_EXECUTABLE)
message(STATUS "use PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}")
endif()

option(BUILD_QT "build QT" ON)
option(BUILD_QT "build with QT" ON)

option(BUILD_METAL "build with Metal" OFF)
message(STATUS "BUILD_METAL: ${BUILD_METAL}")
if(BUILD_METAL)
add_compile_options(-DMODMESH_METAL)
endif()

option(USE_CLANG_TIDY "use clang-tidy" OFF)
option(LINT_AS_ERRORS "clang-tidy warnings as errors" OFF)

Expand All @@ -22,7 +29,7 @@ find_program(
)
if(USE_CLANG_TIDY)
if(CLANG_TIDY_EXE)
set(DO_CLANG_TIDY "${CLANG_TIDY_EXE}")
set(DO_CLANG_TIDY "${CLANG_TIDY_EXE}" "-header-filter=/cpp/.\*")
if(LINT_AS_ERRORS)
set(DO_CLANG_TIDY "${DO_CLANG_TIDY}" "-warnings-as-errors=*")
endif()
Expand Down Expand Up @@ -56,6 +63,10 @@ if(MODMESH_PROFILE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMODMESH_PROFILE")
endif()

if(BUILD_METAL)
include_directories("${CMAKE_CURRENT_LIST_DIR}/thirdparty/install/metal-cpp")
endif()

option(pybind11_path "pybind11 path")
find_package(pybind11 REQUIRED PATHS ${pybind11_path})
message(STATUS "pybind11_INCLUDE_DIRS: ${pybind11_INCLUDE_DIRS}")
Expand Down
39 changes: 25 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ SKIP_PYTHON_EXECUTABLE ?= OFF
HIDE_SYMBOL ?= ON
DEBUG_SYMBOL ?= ON
MODMESH_PROFILE ?= OFF
BUILD_METAL ?= OFF
BUILD_QT ?= ON
USE_CLANG_TIDY ?= OFF
CMAKE_BUILD_TYPE ?= Release
Expand Down Expand Up @@ -108,6 +109,9 @@ cinclude: $(CFFILES)
.PHONY: cmake
cmake: $(BUILD_PATH)/Makefile

.PHONY: xcode
xcode: $(BUILD_PATH)_xcode/Makefile

.PHONY: buildext
buildext: $(MODMESH_ROOT)/modmesh/_modmesh$(pyextsuffix)

Expand All @@ -119,20 +123,27 @@ $(MODMESH_ROOT)/modmesh/_modmesh$(pyextsuffix): $(BUILD_PATH)/Makefile
make -C $(BUILD_PATH) VERBOSE=$(VERBOSE) _modmesh_py $(MAKE_PARALLEL)
touch $@

CMAKE_CMD = cmake $(MODMESH_ROOT) \
-DCMAKE_PREFIX_PATH=$(CMAKE_PREFIX_PATH) \
-DCMAKE_INSTALL_PREFIX=$(CMAKE_INSTALL_PREFIX) \
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=$(CMAKE_LIBRARY_OUTPUT_DIRECTORY) \
-DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) \
-DSKIP_PYTHON_EXECUTABLE=$(SKIP_PYTHON_EXECUTABLE) \
-DHIDE_SYMBOL=$(HIDE_SYMBOL) \
-DDEBUG_SYMBOL=$(DEBUG_SYMBOL) \
-DBUILD_METAL=$(BUILD_METAL) \
-DBUILD_QT=$(BUILD_QT) \
-DUSE_CLANG_TIDY=$(USE_CLANG_TIDY) \
-DLINT_AS_ERRORS=ON \
-DMODMESH_PROFILE=$(MODMESH_PROFILE) \
$(CMAKE_ARGS)

$(BUILD_PATH)/Makefile: CMakeLists.txt Makefile
mkdir -p $(BUILD_PATH) ; \
cd $(BUILD_PATH) ; \
env $(RUNENV) \
cmake $(MODMESH_ROOT) \
-DCMAKE_PREFIX_PATH=$(CMAKE_PREFIX_PATH) \
-DCMAKE_INSTALL_PREFIX=$(CMAKE_INSTALL_PREFIX) \
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=$(CMAKE_LIBRARY_OUTPUT_DIRECTORY) \
-DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) \
-DSKIP_PYTHON_EXECUTABLE=$(SKIP_PYTHON_EXECUTABLE) \
-DHIDE_SYMBOL=$(HIDE_SYMBOL) \
-DDEBUG_SYMBOL=$(DEBUG_SYMBOL) \
-DBUILD_QT=$(BUILD_QT) \
-DUSE_CLANG_TIDY=$(USE_CLANG_TIDY) \
-DLINT_AS_ERRORS=ON \
-DMODMESH_PROFILE=$(MODMESH_PROFILE) \
$(CMAKE_ARGS)
env $(RUNENV) $(CMAKE_CMD)

$(BUILD_PATH)_xcode/Makefile: CMakeLists.txt Makefile
mkdir -p $(BUILD_PATH)_xcode ; \
cd $(BUILD_PATH)_xcode ; \
env $(RUNENV) $(CMAKE_CMD) -G Xcode
2 changes: 1 addition & 1 deletion cmake/Flake8.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ macro(flake8 target_name)
add_custom_command(TARGET ${target_name}
PRE_BUILD
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${flake8_BIN} . --exclude tmp
COMMAND ${flake8_BIN} . --exclude thirdparty,tmp
COMMENT "Running flake8 on ${CMAKE_CURRENT_SOURCE_DIR} ...")
endmacro()
14 changes: 14 additions & 0 deletions cpp/binary/pymod_modmesh/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@ pybind11_add_module(
${MODMESH_PYTHON_HEADERS}
${MODMESH_PYTHON_SOURCES}
)

if(APPLE)
find_library(APPLE_FWK_FOUNDATION Foundation REQUIRED)
find_library(APPLE_FWK_QUARTZ_CORE QuartzCore REQUIRED)
find_library(APPLE_FWK_METAL Metal REQUIRED)

target_link_libraries(
_modmesh PUBLIC
${APPLE_FWK_FOUNDATION}
${APPLE_FWK_QUARTZ_CORE}
${APPLE_FWK_METAL}
)
endif()

if(HIDE_SYMBOL)
set_target_properties(_modmesh PROPERTIES CXX_VISIBILITY_PRESET "hidden")
else()
Expand Down
18 changes: 16 additions & 2 deletions cpp/binary/viewer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,27 @@ qt_add_executable(
${MODMESH_PYMOD_SPACETIME_SOURCES}
)

qt_add_resources(viewer "app_icon"
qt_add_resources(
viewer "app_icon"
PREFIX "/"
BASE ${PROJECT_ROOT_DIR}/resources/viewer
FILES
${PROJECT_ROOT_DIR}/resources/viewer/icon.ico
)

if(APPLE)
find_library(APPLE_FWK_FOUNDATION Foundation REQUIRED)
find_library(APPLE_FWK_QUARTZ_CORE QuartzCore REQUIRED)
find_library(APPLE_FWK_METAL Metal REQUIRED)

target_link_libraries(
viewer PUBLIC
${APPLE_FWK_FOUNDATION}
${APPLE_FWK_QUARTZ_CORE}
${APPLE_FWK_METAL}
)
endif()

if(HIDE_SYMBOL)
set_target_properties(viewer PROPERTIES CXX_VISIBILITY_PRESET "hidden")
else()
Expand Down Expand Up @@ -82,4 +96,4 @@ install(TARGETS viewer
RUNTIME DESTINATION "${INSTALL_VIEWERDIR}"
BUNDLE DESTINATION "${INSTALL_VIEWERDIR}"
LIBRARY DESTINATION "${INSTALL_VIEWERDIR}"
)
)
7 changes: 7 additions & 0 deletions cpp/binary/viewer/viewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
#include <modmesh/spacetime/spacetime.hpp>
#include <modmesh/view/view.hpp>
#include <modmesh/view/wrap_view.hpp>
#ifdef MODMESH_METAL
#include <modmesh/device/metal/metal.hpp>
#endif // MODMESH_METAL

PYBIND11_EMBEDDED_MODULE(_modmesh, mod) // NOLINT
{
Expand All @@ -51,6 +54,10 @@ int main(int argc, char ** argv)
// Set up Python interpreter.
modmesh::python::Interpreter::instance().initialize();

#ifdef MODMESH_METAL
modmesh::device::MetalManager::instance();
#endif // MODMESH_METAL

modmesh::RApplication app(argc, argv);
app.main()->resize(1000, 600);
return app.exec();
Expand Down
12 changes: 12 additions & 0 deletions cpp/modmesh/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,16 @@ set(MODMESH_SOURCES
CACHE FILEPATH "" FORCE
)

if(BUILD_METAL)
add_subdirectory(device/metal)
set(MODMESH_HEADERS
${MODMESH_HEADERS}
${MODMESH_METAL_HEADERS}
CACHE FILEPATH "" FORCE)
set(MODMESH_SOURCES
${MODMESH_SOURCES}
${MODMESH_METAL_SOURCES}
CACHE FILEPATH "" FORCE)
endif()

# vim: set ff=unix fenc=utf8 nobomb et sw=4 ts=4 sts=4:
16 changes: 16 additions & 0 deletions cpp/modmesh/device/metal/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright (c) 2019, Yung-Yu Chen <yyc@solvcon.net>
# BSD-style license; see COPYING

cmake_minimum_required(VERSION 3.16)

set(MODMESH_METAL_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/metal.hpp
CACHE FILEPATH "" FORCE
)

set(MODMESH_METAL_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/metal.cpp
CACHE FILEPATH "" FORCE
)

# vim: set ff=unix fenc=utf8 nobomb et sw=4 ts=4 sts=4:
72 changes: 72 additions & 0 deletions cpp/modmesh/device/metal/metal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright (c) 2022, Yung-Yu Chen <yyc@solvcon.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#define NS_PRIVATE_IMPLEMENTATION
#define CA_PRIVATE_IMPLEMENTATION
#define MTL_PRIVATE_IMPLEMENTATION
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wignored-qualifiers"
#include <Metal/Metal.hpp>
#pragma GCC diagnostic pop

#include <modmesh/device/metal/metal.hpp>

namespace modmesh
{

namespace device
{

MetalManager & MetalManager::instance()
{
static MetalManager o;
return o;
}

void MetalManager::startup()
{
if (nullptr == m_device)
{
m_device = MTL::CreateSystemDefaultDevice();
}
}

void MetalManager::shutdown()
{
if (nullptr != m_device)
{
m_device->release();
m_device = nullptr;
}
}

} /* end namespace device */

} /* end namespace modmesh */

// vim: set ff=unix fenc=utf8 et sw=4 ts=4 sts=4:
72 changes: 72 additions & 0 deletions cpp/modmesh/device/metal/metal.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#pragma once

/*
* Copyright (c) 2022, Yung-Yu Chen <yyc@solvcon.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

// forward declaration.
namespace MTL
{
class Device;
} /* end namespace MTL */

namespace modmesh
{

namespace device
{

class MetalManager
{

public:

static MetalManager & instance();

MetalManager(MetalManager const &) = delete;
MetalManager(MetalManager &&) = delete;
MetalManager & operator=(MetalManager const &) = delete;
MetalManager & operator=(MetalManager &&) = delete;
~MetalManager() { shutdown(); }

void startup();
bool started() { return nullptr != m_device; }
void shutdown();

private:

MetalManager() { startup(); }

MTL::Device * m_device = nullptr;

}; /* end class MetalManager */

} /* end namespace device */

} /* end namespace modmesh */

// vim: set ff=unix fenc=utf8 et sw=4 ts=4 sts=4:
Loading

0 comments on commit f376359

Please sign in to comment.