diff --git a/device/include/roughpy/device/core.h b/device/include/roughpy/device/core.h index 3f94098af..23bb5c818 100644 --- a/device/include/roughpy/device/core.h +++ b/device/include/roughpy/device/core.h @@ -1,40 +1,9 @@ #ifndef ROUGHPY_DEVICE_CORE_H_ #define ROUGHPY_DEVICE_CORE_H_ - -#ifdef __NVCC__ -# include - -# define RPY_DEVICE __device__ -# define RPY_HOST __host__ -# define RPY_DEVICE_HOST __device__ __host__ -# define RPY_KERNEL __global__ -# define RPY_DEVICE_SHARED __shared__ -# define RPY_STRONG_INLINE __inline__ - -#elif defined(__HIPCC__) - -# define RPY_DEVICE __device__ -# define RPY_HOST __host__ -# define RPY_DEVICE_HOST __device__ __host__ -# define RPY_KERNEL __global__ -# define RPY_DEVICE_SHARED __shared__ -# define RPY_STRONG_INLINE - -#else -# define RPY_DEVICE -# define RPY_HOST -# define RPY_DEVICE_HOST -# define RPY_KERNEL -# define RPY_DEVICE_SHARED -# define RPY_STRONG_INLINE - -#endif - namespace rpy { namespace device { -using dindex_t = int; -using dsize_t = unsigned int; + }// namespace device }// namespace rpy diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt index 09c341c67..4ba2e2931 100644 --- a/platform/CMakeLists.txt +++ b/platform/CMakeLists.txt @@ -4,21 +4,24 @@ cmake_minimum_required(VERSION 3.21) project(Roughpy_Platform VERSION 0.0.1) add_roughpy_component(Platform - SOURCES + SOURCES src/configuration.cpp src/threading/openmp_threading.cpp - PUBLIC_HEADERS + src/device.cpp + PUBLIC_HEADERS include/roughpy/platform.h include/roughpy/platform/filesystem.h include/roughpy/platform/configuration.h include/roughpy/platform/serialization.h include/roughpy/platform/threads.h - PUBLIC_DEPS + include/roughpy/platform/device.h + PUBLIC_DEPS Boost::boost Boost::url Boost::disable_autolinking cereal::cereal OpenMP::OpenMP_CXX - NEEDS + NEEDS RoughPy::Core - ) + ) + diff --git a/platform/include/roughpy/platform/device.h b/platform/include/roughpy/platform/device.h new file mode 100644 index 000000000..7c5579f11 --- /dev/null +++ b/platform/include/roughpy/platform/device.h @@ -0,0 +1,130 @@ +// +// Created by sam on 17/08/23. +// + +#ifndef ROUGHPY_DEVICE_H +#define ROUGHPY_DEVICE_H + +#include +#include + +#include "filesystem.h" + +#if defined(__NVCC__) +# include + +# define RPY_DEVICE __device__ +# define RPY_HOST __host__ +# define RPY_DEVICE_HOST __device__ __host__ +# define RPY_KERNEL __global__ +# define RPY_DEVICE_SHARED __shared__ +# define RPY_STRONG_INLINE __inline__ + +#elif defined(__HIPCC__) + +# define RPY_DEVICE __device__ +# define RPY_HOST __host__ +# define RPY_DEVICE_HOST __device__ __host__ +# define RPY_KERNEL __global__ +# define RPY_DEVICE_SHARED __shared__ +# define RPY_STRONG_INLINE + +#else +# define RPY_DEVICE +# define RPY_HOST +# define RPY_DEVICE_HOST +# define RPY_KERNEL +# define RPY_DEVICE_SHARED +# define RPY_STRONG_INLINE + +#endif + + + +namespace rpy { namespace platform { + +using dindex_t = int; +using dsize_t = unsigned int; + + +/** + * @brief Code for different device types + * + * These codes are chosen to be compatible with the DLPack + * array interchange protocol. They enumerate the various different + * device types that scalar data may be allocated on. This code goes + * with a 32bit integer device ID, which is implementation specific. + */ +enum DeviceType : int32_t { + CPU = 1, + CUDA = 2, + CUDAHost = 3, + OpenCL = 4, + Vulkan = 7, + Metal = 8, + VPI = 9, + ROCM = 10, + ROCMHost = 11, + ExtDev = 12, + CUDAManaged = 13, + OneAPI = 14, + WebGPU = 15, + Hexagon = 16 +}; + +/** + * @brief Device type/id pair to identify a device + * + * + */ +struct DeviceInfo { + DeviceType device_type; + int32_t device_id; +}; + + +class RPY_EXPORT DeviceHandle { + DeviceInfo m_info; + +public: + + virtual ~DeviceHandle(); + + explicit DeviceHandle(DeviceInfo info) + : m_info(info) + {} + + explicit DeviceHandle(DeviceType type, int32_t device_id) + : m_info {type, device_id} + {} + + RPY_NO_DISCARD + const DeviceInfo& info() const noexcept { return m_info; } + + RPY_NO_DISCARD + virtual const fs::path& runtime_library() const noexcept = 0; + + + virtual void launch_kernel(const void* kernel, + const void* launch_config, + void** args + ) = 0; + + +}; + + + + + + +constexpr bool +operator==(const DeviceInfo& lhs, const DeviceInfo& rhs) noexcept +{ + return lhs.device_type == rhs.device_type && lhs.device_id == rhs.device_id; +} + +}} + + +#endif// ROUGHPY_DEVICE_H diff --git a/platform/src/device.cpp b/platform/src/device.cpp new file mode 100644 index 000000000..fbc7548c8 --- /dev/null +++ b/platform/src/device.cpp @@ -0,0 +1,13 @@ +// +// Created by sam on 17/08/23. +// + +#include + + +using namespace rpy; +using namespace rpy::platform; + + + +DeviceHandle::~DeviceHandle() = default; \ No newline at end of file diff --git a/roughpy/src/scalars/scalars.cpp b/roughpy/src/scalars/scalars.cpp index 11e5401a3..8561a8803 100644 --- a/roughpy/src/scalars/scalars.cpp +++ b/roughpy/src/scalars/scalars.cpp @@ -139,7 +139,7 @@ void python::init_scalars(pybind11::module_& m) static const scalars::ScalarType* dlpack_dtype_to_scalar_type(DLDataType dtype, DLDevice device) { - using scalars::ScalarDeviceType; + using platform::DeviceType; scalars::ScalarTypeCode type; switch (dtype.code) { @@ -154,7 +154,7 @@ dlpack_dtype_to_scalar_type(DLDataType dtype, DLDevice device) return scalars::ScalarType::from_type_details( {type, dtype.bits, dtype.lanes}, - {static_cast(device.device_type), + {static_cast(device.device_type), device.device_id} ); } diff --git a/scalars/include/roughpy/scalars/scalar_type.h b/scalars/include/roughpy/scalars/scalar_type.h index 579b282d7..7f7ec0b66 100644 --- a/scalars/include/roughpy/scalars/scalar_type.h +++ b/scalars/include/roughpy/scalars/scalar_type.h @@ -77,7 +77,7 @@ class RPY_EXPORT ScalarType template RPY_NO_DISCARD inline static const ScalarType* - of(const ScalarDeviceInfo& device); + of(const platform::DeviceInfo& device); /* * ScalarTypes objects should be unique for each configuration, @@ -106,7 +106,7 @@ class RPY_EXPORT ScalarType * @return const pointer to appropriate scalar type */ RPY_NO_DISCARD static const ScalarType* from_type_details( - const BasicScalarInfo& details, const ScalarDeviceInfo& device + const BasicScalarInfo& details, const platform::DeviceInfo& device ); /** @@ -509,7 +509,7 @@ inline const ScalarType* ScalarType::of() } template -const ScalarType* ScalarType::of(const ScalarDeviceInfo& device) +const ScalarType* ScalarType::of(const platform::DeviceInfo& device) { return get_type(type_id_of(), device); } diff --git a/scalars/include/roughpy/scalars/scalars_fwd.h b/scalars/include/roughpy/scalars/scalars_fwd.h index c64055957..53f72a660 100644 --- a/scalars/include/roughpy/scalars/scalars_fwd.h +++ b/scalars/include/roughpy/scalars/scalars_fwd.h @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -92,32 +93,6 @@ struct signed_size_type_marker { struct unsigned_size_type_marker { }; -/** - * @brief Code for different device types - * - * These codes are chosen to be compatible with the DLPack - * array interchange protocol. They enumerate the various different - * device types that scalar data may be allocated on. This code goes - * with a 32bit integer device ID, which is implementation specific. - */ -enum class ScalarDeviceType : int32_t -{ - CPU = 1, - CUDA = 2, - CUDAHost = 3, - OpenCL = 4, - Vulkan = 7, - Metal = 8, - VPI = 9, - ROCM = 10, - ROCMHost = 11, - ExtDev = 12, - CUDAManaged = 13, - OneAPI = 14, - WebGPU = 15, - Hexagon = 16 -}; - /** * @brief Type codes for different scalar types. * @@ -138,15 +113,6 @@ enum class ScalarTypeCode : uint8_t Bool = 6U }; -/** - * @brief Device type/id pair to identify a device - * - * - */ -struct ScalarDeviceInfo { - ScalarDeviceType device_type; - std::int32_t device_id; -}; /** * @brief Basic information for identifying the type, size, and @@ -168,10 +134,10 @@ struct BasicScalarInfo { struct ScalarTypeInfo { string name; string id; - std::size_t n_bytes; - std::size_t alignment; + size_t n_bytes; + size_t alignment; BasicScalarInfo basic_info; - ScalarDeviceInfo device; + platform::DeviceInfo device; }; // Forward declarations @@ -202,11 +168,6 @@ inline remove_cv_ref_t scalar_cast(const Scalar& arg); using conversion_function = std::function; -constexpr bool -operator==(const ScalarDeviceInfo& lhs, const ScalarDeviceInfo& rhs) noexcept -{ - return lhs.device_type == rhs.device_type && lhs.device_id == rhs.device_id; -} constexpr bool operator==(const BasicScalarInfo& lhs, const BasicScalarInfo& rhs) noexcept @@ -233,7 +194,7 @@ RPY_EXPORT const ScalarType* get_type(const string& id); RPY_EXPORT -const ScalarType* get_type(const string& id, const ScalarDeviceInfo& device); +const ScalarType* get_type(const string& id, const platform::DeviceInfo& device); /** * @brief Get a list of all registered ScalarTypes diff --git a/scalars/src/scalar_implementations/bfloat16/b_float_16_type.cpp b/scalars/src/scalar_implementations/bfloat16/b_float_16_type.cpp index 3edc800ac..fcac50076 100644 --- a/scalars/src/scalar_implementations/bfloat16/b_float_16_type.cpp +++ b/scalars/src/scalar_implementations/bfloat16/b_float_16_type.cpp @@ -31,6 +31,8 @@ #include "b_float_16_type.h" +#include + #include #include @@ -42,5 +44,5 @@ BFloat16Type::BFloat16Type() string("BFloat16"), string("bf16"), sizeof(bfloat16), alignof(bfloat16), {ScalarTypeCode::BFloat, sizeof(bfloat16) * CHAR_BIT, 1U}, - {ScalarDeviceType::CPU, 0}) + {platform::DeviceType::CPU, 0}) {} diff --git a/scalars/src/scalar_implementations/rational/RationalType.cpp b/scalars/src/scalar_implementations/rational/RationalType.cpp index 05a6d004e..804b02d55 100644 --- a/scalars/src/scalar_implementations/rational/RationalType.cpp +++ b/scalars/src/scalar_implementations/rational/RationalType.cpp @@ -73,7 +73,7 @@ RationalType::RationalType() ScalarTypeCode::OpaqueHandle, 0, 0, }, - { ScalarDeviceType::CPU, 0 } + { DeviceType::CPU, 0 } }) {} ScalarPointer RationalType::allocate(std::size_t count) const diff --git a/scalars/src/scalar_implementations/rational_poly/rational_poly_scalar_type.h b/scalars/src/scalar_implementations/rational_poly/rational_poly_scalar_type.h index 1b9763951..a5304f8e4 100644 --- a/scalars/src/scalar_implementations/rational_poly/rational_poly_scalar_type.h +++ b/scalars/src/scalar_implementations/rational_poly/rational_poly_scalar_type.h @@ -32,10 +32,16 @@ #ifndef ROUGHPY_SCALARS_SRC_RATIONAL_POLY_SCALAR_TYPE_H #define ROUGHPY_SCALARS_SRC_RATIONAL_POLY_SCALAR_TYPE_H +#include + #include "conversion.h" #include "scalar_type.h" #include "scalar_type_helper.h" + +using rpy::platform::DeviceType; +using rpy::platform::DeviceInfo; + namespace rpy { namespace scalars { @@ -53,7 +59,7 @@ class RationalPolyScalarType sizeof(rational_poly_scalar), alignof(rational_poly_scalar), {ScalarTypeCode::OpaqueHandle, 0, 0}, - {ScalarDeviceType::CPU, 0}, + {DeviceType::CPU, 0}, }) {} diff --git a/scalars/src/scalar_type.cpp b/scalars/src/scalar_type.cpp index 29faeb6d3..f593a12e6 100644 --- a/scalars/src/scalar_type.cpp +++ b/scalars/src/scalar_type.cpp @@ -48,6 +48,9 @@ using namespace rpy; using namespace scalars; +using rpy::platform::DeviceInfo; +using rpy::platform::DeviceType; + ScalarType::~ScalarType() = default; const ScalarType* ScalarType::rational_type() const noexcept { return this; } @@ -59,10 +62,10 @@ const ScalarType* ScalarType::for_id(const string& id) return ScalarType::of(); } const ScalarType* ScalarType::from_type_details( - const BasicScalarInfo& details, const ScalarDeviceInfo& device + const BasicScalarInfo& details, const DeviceInfo& device ) { - RPY_CHECK(device.device_type == ScalarDeviceType::CPU); + RPY_CHECK(device.device_type == DeviceType::CPU); switch (details.code) { case ScalarTypeCode::Int: RPY_FALLTHROUGH; @@ -205,7 +208,7 @@ rpy::scalars::dtl::scalar_type_holder::get_type() noexcept sizeof(type), \ alignof(type), \ BasicScalarInfo({(code), CHAR_BIT * sizeof(type), 1}), \ - {ScalarDeviceType::CPU, 0}}) + {DeviceType::CPU, 0}}) static const pair reserved[] = {ADD_RES_PAIR("i32", int32_t, ScalarTypeCode::Int), @@ -282,7 +285,7 @@ const ScalarType* rpy::scalars::get_type(const string& id) } const ScalarType* -scalars::get_type(const string& id, const ScalarDeviceInfo& device) +scalars::get_type(const string& id, const DeviceInfo& device) { // TODO: Needs implementation return nullptr; diff --git a/scalars/src/standard_scalar_type.h b/scalars/src/standard_scalar_type.h index d8a2943d2..b3ad55dcb 100644 --- a/scalars/src/standard_scalar_type.h +++ b/scalars/src/standard_scalar_type.h @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -47,6 +48,9 @@ #include "standard_random_generator.h" +using rpy::platform::DeviceType; +using rpy::platform::DeviceInfo; + namespace rpy { namespace scalars { @@ -90,7 +94,7 @@ class StandardScalarType : public impl_helpers::ScalarTypeHelper sizeof(ScalarImpl), alignof(ScalarImpl), {ScalarTypeCode::Float, sizeof_bits(), 1U}, - {ScalarDeviceType::CPU, 0} + {DeviceType::CPU, 0} }) {} @@ -100,7 +104,7 @@ class StandardScalarType : public impl_helpers::ScalarTypeHelper explicit StandardScalarType( string name, string id, std::size_t size, std::size_t align, - BasicScalarInfo basic_info, ScalarDeviceInfo device_info + BasicScalarInfo basic_info, DeviceInfo device_info ) : helper({name, id, size, align, basic_info, device_info}) {} diff --git a/scalars/src/test_scalar_type.cpp b/scalars/src/test_scalar_type.cpp index 5eb61f7ba..4f8042472 100644 --- a/scalars/src/test_scalar_type.cpp +++ b/scalars/src/test_scalar_type.cpp @@ -39,6 +39,9 @@ using ScalarTypeTests = rpy::scalars::testing::ScalarTests; using namespace rpy::scalars; +using rpy::platform::DeviceType; +using rpy::platform::DeviceInfo; + class RAIIAlloc { ScalarPointer m_ptr; @@ -66,7 +69,7 @@ TEST_F(ScalarTypeTests, BasicInfoFloat) ASSERT_EQ(info.name, "SPReal"); ASSERT_EQ(info.id, "f32"); - ASSERT_EQ(info.device.device_type, ScalarDeviceType::CPU); + ASSERT_EQ(info.device.device_type, DeviceType::CPU); ASSERT_EQ(info.device.device_id, 0); ASSERT_EQ(info.basic_info.bits, sizeof(float) * 8); ASSERT_EQ(info.basic_info.code, ScalarTypeCode::Float); @@ -82,7 +85,7 @@ TEST_F(ScalarTypeTests, BasicInfoDouble) ASSERT_EQ(info.name, "DPReal"); ASSERT_EQ(info.id, "f64"); - ASSERT_EQ(info.device.device_type, ScalarDeviceType::CPU); + ASSERT_EQ(info.device.device_type, DeviceType::CPU); ASSERT_EQ(info.device.device_id, 0); ASSERT_EQ(info.basic_info.bits, sizeof(double) * 8); ASSERT_EQ(info.basic_info.code, ScalarTypeCode::Float);