Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add macOS support #602

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 47 additions & 21 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,30 @@

# temporary
set(CMAKE_WARN_DEPRECATED OFF)
add_compile_options(-Wno-format-extra-args -mf16c)

# Workaround for https://gitlab.kitware.com/cmake/cmake/-/issues/17702
#FIXME: For my machine (Apple M1 Max), this just returns ""
message("ARCH <${CMAKE_SYSTEM_PROCESSOR}> <${CMAKE_HOST_SYSTEM_PROCESSOR}>")
# From PROCESSOR_ARCHITECTURE, see https://learn.microsoft.com/en-us/windows/win32/winprog64/wow64-implementation-details?redirectedfrom=MSDN
if ("{CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64")
set(ARCH "x64")
elseif ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86")
set(ARCH "x86")
# From uname -p
elseif ("{CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i386")
# We can't differentiate x86 or x64, but we guess x64
set(ARCH "x64")
else()
set(ARCH "unknown")
endif()
Copy link
Author

Choose a reason for hiding this comment

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

This entire block is super ugly. I'm not sure how to do this best


add_compile_options(-Wno-format-extra-args)
if("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "x86")
add_compile_options(-mf16c)
elseif("${CMAKE_C_COMPILER_ARCHITECTURE_ID}" STREQUAL "x64")
add_compile_options(-mf16c)
endif()
Copy link
Author

Choose a reason for hiding this comment

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

How important is -mf16c for x86? Could it be removed? It's in a "temporary" block, too.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I recall, the -mf16c is required for host side native half type and operations (hip_fp16.h).

Copy link
Collaborator

Choose a reason for hiding this comment

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

Correction: the -mf16c is used for working around an undefined reference issue. However, the same issue is seen here too despite the workaround so I’m not sure if the option is actually effective.


set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-duplicate-decl-specifier \
-Wno-tautological-constant-compare -Wno-c++20-extensions -Wno-unused-result \
Expand Down Expand Up @@ -67,13 +90,16 @@ endforeach()
# chipStar CMAKE DEPENDENCIES
if(NOT DEFINED OpenCL_LIBRARY)
message(STATUS "OpenCL_LIBRARY was not set. Searching for libOpenCL.so in LD_LIBRARY_PATH")
find_library(OpenCL_LIBRARY NAMES OpenCL PATHS ENV LD_LIBRARY_PATH ./ NO_CACHE)
if(OpenCL_LIBRARY)
get_filename_component(OpenCL_DIR ${OpenCL_LIBRARY} DIRECTORY CACHE)
message(STATUS "Setting OpenCL_DIR to ${OpenCL_DIR}")
else()
message(STATUS "OpenCL not found")
endif()
#find_library(OpenCL_LIBRARY NAMES OpenCL PATHS ENV LD_LIBRARY_PATH ./ NO_CACHE)

find_package(OpenCLHeaders)
find_package(OpenCLICDLoader)

#add_library(OpenCL ALIAS OpenCLICDLoader)
Copy link
Author

Choose a reason for hiding this comment

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

Dead code

message("OpenCL_FOUND: ${OpenCL_FOUND}")
set(OpenCL_FOUND ${OpenCLICDLoader_FOUND})
message("OpenCL_FOUND: ${OpenCL_FOUND}")
Copy link
Author

Choose a reason for hiding this comment

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

Debug leftover


endif()

if(NOT DEFINED LevelZero_LIBRARY)
Expand Down Expand Up @@ -114,10 +140,10 @@ if(NOT DEFINED LevelZero_LIBRARY)
endif()
endif()

message(STATUS "OpenCL_LIBRARY: ${OpenCL_LIBRARY}")
message(STATUS "OpenCL_FOUND: ${OpenCL_FOUND}")
Copy link
Author

Choose a reason for hiding this comment

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

This is obviously ugly; I'll have to figure out how to show the path with import targets.
Maybe it's also enough to report YES / NO for each of these.

message(STATUS "LevelZero_LIBRARY: ${LevelZero_LIBRARY}")

if(NOT OpenCL_LIBRARY AND NOT LevelZero_LIBRARY)
if(NOT OpenCL_FOUND AND NOT LevelZero_LIBRARY)
message(FATAL_ERROR "At least one of OpenCL,Level0 libraries must be available")
endif()

Expand Down Expand Up @@ -155,7 +181,7 @@ set(CHIP_SRC
src/SPIRVFuncInfo.cc
)

if(OpenCL_LIBRARY)
if(OpenCL_FOUND)
list(APPEND CHIP_SRC
src/backend/OpenCL/CHIPBackendOpenCL.cc
src/backend/OpenCL/SVMemoryRegion.cc)
Expand Down Expand Up @@ -313,18 +339,18 @@ endif()
if(CHIP_BUILD_SHARED_LIBS)
message(STATUS "Buiding chipStar as a shared library")
add_library(CHIP SHARED ${CHIP_SRC})
set(CHIP_LIB_NAME "libCHIP.so")
else()
message(STATUS "Buiding chipStar as a static library")
add_library(CHIP STATIC ${CHIP_SRC})
set(CHIP_LIB_NAME "libCHIP.a")
endif()

set(CHIP_INTERFACE_LIBS ${PTHREAD_LIBRARY})

if(OpenCL_LIBRARY)
if(OpenCL_FOUND)
list(APPEND CHIP_SPV_DEFINITIONS HAVE_OPENCL)
list(PREPEND CHIP_INTERFACE_LIBS ${OpenCL_LIBRARY})
list(PREPEND CHIP_INTERFACE_LIBS
#OpenCL::Headers
Copy link
Author

Choose a reason for hiding this comment

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

Deadcode

OpenCL::OpenCL)
endif()

if(LevelZero_LIBRARY)
Expand Down Expand Up @@ -452,10 +478,10 @@ set(HIP_OFFLOAD_COMPILE_OPTIONS_BUILD_
list(APPEND HIP_OFFLOAD_LINK_OPTIONS_INSTALL_ "-L${LIB_INSTALL_DIR}" "-lCHIP")
list(APPEND HIP_OFFLOAD_LINK_OPTIONS_BUILD_ "-L${CMAKE_BINARY_DIR}" "-lCHIP")

if(OpenCL_LIBRARY)
target_link_options(CHIP PUBLIC -Wl,-rpath,${OpenCL_DIR})
target_link_directories(CHIP PUBLIC ${OpenCL_DIR})
target_link_libraries(CHIP PUBLIC OpenCL)
if(OpenCL_FOUND)
target_link_libraries(CHIP PUBLIC
# OpenCL::Headers
OpenCL::OpenCL)
endif()

if(LevelZero_LIBRARY)
Expand Down Expand Up @@ -662,7 +688,7 @@ install(TARGETS CHIP
)

install(FILES ${CMAKE_BINARY_DIR}/include/CHIPSPVConfig.hh DESTINATION ${INCLUDE_INSTALL_DIR})
install(FILES ${PROJECT_BINARY_DIR}/${CHIP_LIB_NAME} DESTINATION lib)
install(TARGETS CHIP)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/HIP/include DESTINATION . USE_SOURCE_PERMISSIONS)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include DESTINATION . USE_SOURCE_PERMISSIONS)

Expand Down Expand Up @@ -708,7 +734,7 @@ endif()

# Short Summary
# print if Level Zero or OpenCL are enabbled
if(OpenCL_LIBRARY)
if(OpenCL_FOUND)
message(STATUS "OpenCL is enabled: ${OpenCL_LIBRARY}")
endif()

Expand Down
5 changes: 4 additions & 1 deletion include/CL/opencl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,10 @@
#endif

#if defined(__APPLE__) || defined(__MACOSX)
#include <OpenCL/opencl.h>
#define CL_DEPRECATED(...)
#define GCL_API_SUFFIX__VERSION_1_1
//#include <OpenCL/opencl.h>
#include <CL/opencl.h>
Copy link
Author

Choose a reason for hiding this comment

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

Can probably be changed back; I believe ICD Loader also overloads <OpenCL/opencl.h>

#else
#include <CL/opencl.h>
#endif // !__APPLE__
Expand Down
3 changes: 3 additions & 0 deletions include/hip/devicelib/macros.hh
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,7 @@
typedef _Float16 api_half;
typedef _Float16 api_half2 __attribute__((ext_vector_type(2)));

typedef unsigned int uint;
typedef unsigned long ulong;
Copy link
Author

Choose a reason for hiding this comment

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

Why is this necessary on macOS? Does it still work for other platforms or will it report duplicate identifier?

Copy link
Collaborator

Choose a reason for hiding this comment

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

It might cause troubles. On my system (Ubuntu 22.04) <stdlib.h> includes <sys/types.h> which defines typedefs for u{short,int,long}.

/usr/include/x86_64-linux-gnu/sys/types.h:

...
#ifdef __USE_MISC
/* Old compatibility names for C types.  */
typedef unsigned long int ulong;
typedef unsigned short int ushort;
typedef unsigned int uint;
#endif
...

Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually, it's not a problem as long as the duplicate typedefs aliases the same type.


#endif // include guard
22 changes: 0 additions & 22 deletions include/spdlog/LICENSE

This file was deleted.

42 changes: 27 additions & 15 deletions include/spdlog/async.h
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@

//
// Copyright(c) 2018 Gabi Melman.
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//

#pragma once

//
// Async logging using global thread pool
// All loggers created here share same global thread pool.
// Each log message is pushed to a queue along withe a shared pointer to the
// Each log message is pushed to a queue along with a shared pointer to the
// logger.
// If a logger deleted while having pending messages in the queue, it's actual
// destruction will defer
// until all its messages are processed by the thread pool.
// This is because each message in the queue holds a shared_ptr to the
// originating logger.

#include "spdlog/async_logger.h"
#include "spdlog/details/registry.h"
#include "spdlog/details/thread_pool.h"
#include <spdlog/async_logger.h>
#include <spdlog/details/registry.h>
#include <spdlog/details/thread_pool.h>

#include <memory>
#include <mutex>
#include <functional>

namespace spdlog {

Expand All @@ -37,16 +35,18 @@ template<async_overflow_policy OverflowPolicy = async_overflow_policy::block>
struct async_factory_impl
{
template<typename Sink, typename... SinkArgs>
static std::shared_ptr<async_logger> create(std::string logger_name, SinkArgs &&... args)
static std::shared_ptr<async_logger> create(std::string logger_name, SinkArgs &&...args)
{
auto &registry_inst = details::registry::instance();

// create global thread pool if not already exists..
std::lock_guard<std::recursive_mutex> tp_lock(registry_inst.tp_mutex());

auto &mutex = registry_inst.tp_mutex();
std::lock_guard<std::recursive_mutex> tp_lock(mutex);
auto tp = registry_inst.get_tp();
if (tp == nullptr)
{
tp = std::make_shared<details::thread_pool>(details::default_async_q_size, 1);
tp = std::make_shared<details::thread_pool>(details::default_async_q_size, 1U);
registry_inst.set_tp(tp);
}

Expand All @@ -61,24 +61,36 @@ using async_factory = async_factory_impl<async_overflow_policy::block>;
using async_factory_nonblock = async_factory_impl<async_overflow_policy::overrun_oldest>;

template<typename Sink, typename... SinkArgs>
inline std::shared_ptr<spdlog::logger> create_async(std::string logger_name, SinkArgs &&... sink_args)
inline std::shared_ptr<spdlog::logger> create_async(std::string logger_name, SinkArgs &&...sink_args)
{
return async_factory::create<Sink>(std::move(logger_name), std::forward<SinkArgs>(sink_args)...);
}

template<typename Sink, typename... SinkArgs>
inline std::shared_ptr<spdlog::logger> create_async_nb(std::string logger_name, SinkArgs &&... sink_args)
inline std::shared_ptr<spdlog::logger> create_async_nb(std::string logger_name, SinkArgs &&...sink_args)
{
return async_factory_nonblock::create<Sink>(std::move(logger_name), std::forward<SinkArgs>(sink_args)...);
}

// set global thread pool.
inline void init_thread_pool(size_t q_size, size_t thread_count)
inline void init_thread_pool(
size_t q_size, size_t thread_count, std::function<void()> on_thread_start, std::function<void()> on_thread_stop)
{
auto tp = std::make_shared<details::thread_pool>(q_size, thread_count);
auto tp = std::make_shared<details::thread_pool>(q_size, thread_count, on_thread_start, on_thread_stop);
details::registry::instance().set_tp(std::move(tp));
}

inline void init_thread_pool(size_t q_size, size_t thread_count, std::function<void()> on_thread_start)
{
init_thread_pool(q_size, thread_count, on_thread_start, [] {});
}

inline void init_thread_pool(size_t q_size, size_t thread_count)
{
init_thread_pool(
q_size, thread_count, [] {}, [] {});
}

// get the global thread pool.
inline std::shared_ptr<spdlog::details::thread_pool> thread_pool()
{
Expand Down
90 changes: 90 additions & 0 deletions include/spdlog/async_logger-inl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)

#pragma once

#ifndef SPDLOG_HEADER_ONLY
# include <spdlog/async_logger.h>
#endif

#include <spdlog/sinks/sink.h>
#include <spdlog/details/thread_pool.h>

#include <memory>
#include <string>

SPDLOG_INLINE spdlog::async_logger::async_logger(
std::string logger_name, sinks_init_list sinks_list, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy)
: async_logger(std::move(logger_name), sinks_list.begin(), sinks_list.end(), std::move(tp), overflow_policy)
{}

SPDLOG_INLINE spdlog::async_logger::async_logger(
std::string logger_name, sink_ptr single_sink, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy)
: async_logger(std::move(logger_name), {std::move(single_sink)}, std::move(tp), overflow_policy)
{}

// send the log message to the thread pool
SPDLOG_INLINE void spdlog::async_logger::sink_it_(const details::log_msg &msg){
SPDLOG_TRY{if (auto pool_ptr = thread_pool_.lock()){pool_ptr->post_log(shared_from_this(), msg, overflow_policy_);
}
else
{
throw_spdlog_ex("async log: thread pool doesn't exist anymore");
}
}
SPDLOG_LOGGER_CATCH(msg.source)
}

// send flush request to the thread pool
SPDLOG_INLINE void spdlog::async_logger::flush_(){
SPDLOG_TRY{if (auto pool_ptr = thread_pool_.lock()){pool_ptr->post_flush(shared_from_this(), overflow_policy_);
}
else
{
throw_spdlog_ex("async flush: thread pool doesn't exist anymore");
}
}
SPDLOG_LOGGER_CATCH(source_loc())
}

//
// backend functions - called from the thread pool to do the actual job
//
SPDLOG_INLINE void spdlog::async_logger::backend_sink_it_(const details::log_msg &msg)
{
for (auto &sink : sinks_)
{
if (sink->should_log(msg.level))
{
SPDLOG_TRY
{
sink->log(msg);
}
SPDLOG_LOGGER_CATCH(msg.source)
}
}

if (should_flush_(msg))
{
backend_flush_();
}
}

SPDLOG_INLINE void spdlog::async_logger::backend_flush_()
{
for (auto &sink : sinks_)
{
SPDLOG_TRY
{
sink->flush();
}
SPDLOG_LOGGER_CATCH(source_loc())
}
}

SPDLOG_INLINE std::shared_ptr<spdlog::logger> spdlog::async_logger::clone(std::string new_name)
{
auto cloned = std::make_shared<spdlog::async_logger>(*this);
cloned->name_ = std::move(new_name);
return cloned;
}
Loading