Skip to content

Commit

Permalink
bump version, merge pull request #42 from AMYPAD/clean-api
Browse files Browse the repository at this point in the history
  • Loading branch information
casperdcl committed Feb 26, 2024
2 parents 3ff22d6 + 7f95eaf commit b9a12bd
Show file tree
Hide file tree
Showing 27 changed files with 333 additions and 294 deletions.
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ on:
push:
pull_request:
schedule: [{cron: '30 23 * * 6'}] # M H d m w (Sat at 23:30)
workflow_dispatch:
jobs:
clang-format:
if: github.event_name != 'pull_request' || !contains('OWNER,MEMBER,COLLABORATOR', github.event.pull_request.author_association)
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ __pycache__/
/cuvec-*.dist-info/
/cuvec/*PYTHON_wrap.cxx
/cuvec/example_swig.py
/cuvec/swvec.py
/cuvec/cuvec_swig.py
/dist/
/build/
/docs/build/
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
# since `-e .` doesn't work yet (https://github.com/scikit-build/scikit-build-core/issues/114).
# Instead, do `make deps-build build-editable deps-run`
CUVEC_DEBUG=0
BUILD_TYPE=RelWithDebInfo
CXX_FLAGS=-Wall -Wextra -Wpedantic -Werror -Wno-missing-field-initializers -Wno-unused-parameter -Wno-cast-function-type
CUDA_ARCHITECTURES=native
BUILD_CMAKE_FLAGS=-Ccmake.define.CUVEC_DEBUG=$(CUVEC_DEBUG) -Ccmake.define.CMAKE_CXX_FLAGS="$(CXX_FLAGS)" -Ccmake.define.CMAKE_CUDA_ARCHITECTURES=$(CUDA_ARCHITECTURES)
BUILD_CMAKE_FLAGS=-Ccmake.define.CUVEC_DEBUG=$(CUVEC_DEBUG) -Ccmake.define.CMAKE_BUILD_TYPE=$(BUILD_TYPE) -Ccmake.define.CMAKE_CXX_FLAGS="$(CXX_FLAGS)" -Ccmake.define.CMAKE_CUDA_ARCHITECTURES=$(CUDA_ARCHITECTURES)
CCACHE=
ifneq ($(CCACHE),)
BUILD_CMAKE_FLAGS+= -Ccmake.define.CMAKE_CXX_COMPILER_LAUNCHER=ccache
Expand Down
35 changes: 17 additions & 18 deletions cuvec/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ cmake_policy(POP)

message(STATUS "CUDA architectures: ${CMAKE_CUDA_ARCHITECTURES}")
if(NOT DEFINED CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Build type" FORCE)
endif()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")

Expand Down Expand Up @@ -97,16 +97,15 @@ if(pybind11_FOUND AND SKBUILD)
file(GLOB SRC LIST_DIRECTORIES false "src/pybind11*.cu")
# include_directories(src)
# include_directories(${Python_INCLUDE_DIRS})
python_add_library(${PROJECT_NAME}_pybind11 MODULE WITH_SOABI ${SRC})
pybind11_add_module(${PROJECT_NAME}_pybind11 MODULE WITH_SOABI ${SRC})
add_library(AMYPAD::${PROJECT_NAME}_pybind11 ALIAS ${PROJECT_NAME}_pybind11)
target_include_directories(${PROJECT_NAME}_pybind11 PUBLIC
"$<BUILD_INTERFACE:${${CMAKE_PROJECT_NAME}_INCLUDE_DIRS}>"
"$<INSTALL_INTERFACE:${CMAKE_PROJECT_NAME}/include>")
if(CUDAToolkit_FOUND)
target_link_libraries(${PROJECT_NAME}_pybind11 PRIVATE pybind11::headers CUDA::cudart_static)
target_link_libraries(${PROJECT_NAME}_pybind11 PRIVATE CUDA::cudart_static)
else()
set_source_files_properties(${SRC} PROPERTIES LANGUAGE CXX)
target_link_libraries(${PROJECT_NAME}_pybind11 PRIVATE pybind11::headers)
endif()

set_target_properties(${PROJECT_NAME}_pybind11 PROPERTIES
Expand All @@ -124,32 +123,32 @@ endif()
if(SWIG_FOUND AND SKBUILD)
if(CUDAToolkit_FOUND)
include_directories(${CUDAToolkit_INCLUDE_DIRS})
set_source_files_properties(src/swvec.i PROPERTIES COMPILE_DEFINITIONS _CUVEC_HALF=__half)
set_source_files_properties(src/cuvec_swig.i PROPERTIES COMPILE_DEFINITIONS _CUVEC_HALF=__half)
endif()
set_source_files_properties(src/swvec.i PROPERTIES CPLUSPLUS ON)
set_source_files_properties(src/swvec.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON)
swig_add_library(swvec LANGUAGE python
set_source_files_properties(src/cuvec_swig.i PROPERTIES CPLUSPLUS ON)
set_source_files_properties(src/cuvec_swig.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON)
swig_add_library(${PROJECT_NAME}_swig LANGUAGE python
OUTPUT_DIR "${SKBUILD_PLATLIB_DIR}/${CMAKE_PROJECT_NAME}"
SOURCES src/swvec.i)
SOURCES src/cuvec_swig.i)
if(WIN32)
set_property(TARGET swvec PROPERTY SUFFIX ".${Python_SOABI}.pyd")
set_property(TARGET ${PROJECT_NAME}_swig PROPERTY SUFFIX ".${Python_SOABI}.pyd")
else()
set_property(TARGET swvec PROPERTY SUFFIX ".${Python_SOABI}${CMAKE_SHARED_MODULE_SUFFIX}")
set_property(TARGET ${PROJECT_NAME}_swig PROPERTY SUFFIX ".${Python_SOABI}${CMAKE_SHARED_MODULE_SUFFIX}")
endif()
if(CUDAToolkit_FOUND)
target_link_libraries(swvec PRIVATE Python::Module CUDA::cudart_static)
target_link_libraries(${PROJECT_NAME}_swig PRIVATE Python::Module CUDA::cudart_static)
else()
target_link_libraries(swvec PRIVATE Python::Module)
target_link_libraries(${PROJECT_NAME}_swig PRIVATE Python::Module)
endif()
target_include_directories(swvec PUBLIC
target_include_directories(${PROJECT_NAME}_swig PUBLIC
"$<BUILD_INTERFACE:${${CMAKE_PROJECT_NAME}_INCLUDE_DIRS}>"
"$<INSTALL_INTERFACE:${CMAKE_PROJECT_NAME}/include>")
set_target_properties(swvec PROPERTIES
set_target_properties(${PROJECT_NAME}_swig PROPERTIES
CXX_STANDARD 11
VERSION ${CMAKE_PROJECT_VERSION} SOVERSION ${CMAKE_PROJECT_VERSION_MAJOR}
INTERFACE_swvec_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR})
set_property(TARGET swvec APPEND PROPERTY COMPATIBLE_INTERFACE_STRING swvec_MAJOR_VERSION)
install(TARGETS swvec
INTERFACE_${PROJECT_NAME}_swig_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR})
set_property(TARGET ${PROJECT_NAME}_swig APPEND PROPERTY COMPATIBLE_INTERFACE_STRING ${PROJECT_NAME}_swig_MAJOR_VERSION)
install(TARGETS ${PROJECT_NAME}_swig
INCLUDES DESTINATION ${CMAKE_PROJECT_NAME}/include
LIBRARY DESTINATION ${CMAKE_PROJECT_NAME})
endif()
Expand Down
4 changes: 4 additions & 0 deletions cuvec/cpython.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,12 @@ def __new__(cls, arr):
(do not do `cuvec.CuVec((42, 1337))`;
instead use `cuvec.zeros((42, 137))`"""))

__array_interface__: Dict[str,
Any] # <https://numpy.org/doc/stable/reference/arrays.interface.html>

@property
def __cuda_array_interface__(self) -> Dict[str, Any]:
"""<https://numba.readthedocs.io/en/stable/cuda/cuda_array_interface.html>"""
if not hasattr(self, 'cuvec'):
raise AttributeError(
dedent("""\
Expand Down
36 changes: 3 additions & 33 deletions cuvec/include/cuvec.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@
* Pure CUDA/C++11 template header. Provides:
* - CuVec<T> // analogous to `std::vector` but using CUDA unified memory
*
* SWIG helpers wrapping `CuVec<T>`. Provides:
* - SwigCuVec<T> // contains `CuVec<T> vec` and `std::vector<size_t> shape`
* - SwigCuVec<T> *SwigCuVec_new(std::vector<size_t> shape)
* - void SwigCuVec_del(SwigCuVec<T> *self)
* - T *SwigCuVec_data(SwigCuVec<T> *self)
* - size_t SwigCuVec_address(SwigCuVec<T> *self)
* - std::vector<size_t> SwigCuVec_shape(SwigCuVec<T> *self)
* Helpers wrapping `CuVec<T>`. Provides:
* - NDCuVec<T> // contains `CuVec<T> vec` and `std::vector<size_t> shape`
*/
#ifndef _CUVEC_H_
#define _CUVEC_H_
Expand Down Expand Up @@ -101,7 +96,7 @@ template <class T> using CuVec = std::vector<T, CuAlloc<T>>;
#endif // CUVEC_DISABLE_CUDA
#endif // _CUVEC_HALF

/// pybind11 helpers
/// external wrapper helper
template <class T> struct NDCuVec {
CuVec<T> vec;
std::vector<size_t> shape;
Expand All @@ -117,31 +112,6 @@ template <class T> struct NDCuVec {
if (size != vec.size()) throw std::length_error("reshape: size mismatch");
this->shape = shape;
}
~NDCuVec() {
vec.clear();
vec.shrink_to_fit();
shape.clear();
shape.shrink_to_fit();
}
};

/// SWIG helpers
template <class T> using SwigCuVec = NDCuVec<T>;
template <class T> SwigCuVec<T> *SwigCuVec_new(std::vector<size_t> shape) {
SwigCuVec<T> *self = new SwigCuVec<T>(shape);
return self;
}
template <class T> void SwigCuVec_del(SwigCuVec<T> *self) {
self->~NDCuVec();
delete self;
}
template <class T> T *SwigCuVec_data(SwigCuVec<T> *self) { return self->vec.data(); }
template <class T> size_t SwigCuVec_address(SwigCuVec<T> *self) {
return (size_t)SwigCuVec_data(self);
}
template <class T> std::vector<size_t> SwigCuVec_shape(SwigCuVec<T> *self) { return self->shape; }
template <class T> void SwigCuVec_reshape(SwigCuVec<T> *self, const std::vector<size_t> &shape) {
self->reshape(shape);
}

#endif // _CUVEC_H_
6 changes: 3 additions & 3 deletions cuvec/include/cuvec.i
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/**
* SWIG template header wrapping `SwigCuVec<T>` as defined in "cuvec.cuh"
* SWIG template header wrapping `NDCuVec<T>` as defined in "cuvec.cuh"
* for external use via `%include "cuvec.i"`.
*/
%include "std_vector.i"
%{
#include "cuvec.cuh" // SwigCuVec<T>
#include "cuvec.cuh" // NDCuVec<T>
%}
/// expose definitions
template <class T> struct SwigCuVec {
template <class T> struct NDCuVec {
CuVec<T> vec;
std::vector<size_t> shape;
};
5 changes: 2 additions & 3 deletions cuvec/include/cuvec_pybind11.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ PYBIND11_MAKE_OPAQUE(NDCuVec<double>);
.def(pybind11::init<>()) \
.def(pybind11::init<std::vector<size_t>>()) \
.def_property( \
"shape", [](const NDCuVec<T> *v) { return &(v->shape); }, &NDCuVec<T>::reshape) \
.def_property_readonly("address", \
[](const NDCuVec<T> *v) { return (size_t)v->vec.data(); })
"shape", [](const NDCuVec<T> &v) { return &v.shape; }, &NDCuVec<T>::reshape) \
.def_property_readonly("address", [](const NDCuVec<T> &v) { return (size_t)v.vec.data(); })

#endif // _CUVEC_PYBIND11_H_
1 change: 1 addition & 0 deletions cuvec/include/pycuvec.cuh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "cuvec_cpython.cuh" // deprecated alias
18 changes: 15 additions & 3 deletions cuvec/pybind11.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from collections.abc import Sequence
from functools import partial
from textwrap import dedent
from typing import Any, Dict, Optional
from typing import Any, Dict, Optional, Tuple

import numpy as np

Expand All @@ -35,7 +35,7 @@ def __init__(self, typechar: str, shape: Shape, cuvec=None):
cuvec(NDCuVec<Type>): if given, `typechar` and `shape` are ignored
"""
if cuvec is None:
shape = cu.Shape(shape if isinstance(shape, Sequence) else (shape,))
shape = shape if isinstance(shape, Sequence) else (shape,)
cuvec = getattr(cu, f'NDCuVec_{typechar}')(shape)
else:
typechar = self.is_raw_cuvec(cuvec).group(1)
Expand All @@ -48,7 +48,7 @@ def shape(self) -> tuple:

@shape.setter
def shape(self, shape: Shape):
shape = cu.Shape(shape if isinstance(shape, Sequence) else (shape,))
shape = shape if isinstance(shape, Sequence) else (shape,)
self.cuvec.shape = shape

@property
Expand Down Expand Up @@ -87,8 +87,12 @@ def __new__(cls, arr):
(do not do `cuvec.pybind11.CuVec((42, 1337))`;
instead use `cuvec.pybind11.zeros((42, 137))`"""))

__array_interface__: Dict[str,
Any] # <https://numpy.org/doc/stable/reference/arrays.interface.html>

@property
def __cuda_array_interface__(self) -> Dict[str, Any]:
"""<https://numba.readthedocs.io/en/stable/cuda/cuda_array_interface.html>"""
if not hasattr(self, 'cuvec'):
raise AttributeError(
dedent("""\
Expand All @@ -101,6 +105,14 @@ def resize(self, new_shape: Shape):
self._vec.shape = new_shape
super().resize(new_shape, refcheck=False)

@property
def shape(self) -> Tuple[int, ...]:
return super().shape

@shape.setter
def shape(self, new_shape: Shape):
self.resize(new_shape)


def zeros(shape: Shape, dtype="float32") -> CuVec:
"""
Expand Down
58 changes: 58 additions & 0 deletions cuvec/src/cuvec_swig.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
%module cuvec_swig

%include "exception.i"
%exception {
try {
$action
} catch (const std::exception &e) {
SWIG_exception(SWIG_RuntimeError, e.what());
}
}

%include "cuvec.i" // NDCuVec<T>

%{
template <class T> NDCuVec<T> *NDCuVec_new(std::vector<size_t> shape) {
NDCuVec<T> *self = new NDCuVec<T>(shape);
return self;
}
template <class T> void NDCuVec_del(NDCuVec<T> *self) {
delete self;
}
template <class T> size_t NDCuVec_address(NDCuVec<T> *self) {
return (size_t)self->vec.data();
}
template <class T> std::vector<size_t> NDCuVec_shape(NDCuVec<T> *self) { return self->shape; }
template <class T> void NDCuVec_reshape(NDCuVec<T> *self, const std::vector<size_t> &shape) {
self->reshape(shape);
}
%}
template <class T> NDCuVec<T> *NDCuVec_new(std::vector<size_t> shape);
template <class T> void NDCuVec_del(NDCuVec<T> *self);
template <class T> size_t NDCuVec_address(NDCuVec<T> *self);
template <class T> std::vector<size_t> NDCuVec_shape(NDCuVec<T> *self);
template <class T> void NDCuVec_reshape(NDCuVec<T> *self, const std::vector<size_t> &shape);

%template(NDCuVec_Shape) std::vector<size_t>;
%define MKCUVEC(T, typechar)
%template(NDCuVec_ ## typechar) NDCuVec<T>;
%template(NDCuVec_ ## typechar ## _new) NDCuVec_new<T>;
%template(NDCuVec_ ## typechar ## _del) NDCuVec_del<T>;
%template(NDCuVec_ ## typechar ## _address) NDCuVec_address<T>;
%template(NDCuVec_ ## typechar ## _shape) NDCuVec_shape<T>;
%template(NDCuVec_ ## typechar ## _reshape) NDCuVec_reshape<T>;
%enddef
MKCUVEC(signed char, b)
MKCUVEC(unsigned char, B)
MKCUVEC(char, c)
MKCUVEC(short, h)
MKCUVEC(unsigned short, H)
MKCUVEC(int, i)
MKCUVEC(unsigned int, I)
MKCUVEC(long long, q)
MKCUVEC(unsigned long long, Q)
#ifdef _CUVEC_HALF
MKCUVEC(_CUVEC_HALF, e)
#endif
MKCUVEC(float, f)
MKCUVEC(double, d)
5 changes: 2 additions & 3 deletions cuvec/src/example_pybind11/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ file(GLOB SRC LIST_DIRECTORIES false "*.cu")
if(CUDAToolkit_FOUND)
include_directories(${CUDAToolkit_INCLUDE_DIRS})
endif()
python_add_library(${PROJECT_NAME} MODULE WITH_SOABI ${SRC})
pybind11_add_module(${PROJECT_NAME} MODULE WITH_SOABI ${SRC})
target_include_directories(${PROJECT_NAME} PUBLIC
"$<BUILD_INTERFACE:${${CMAKE_PROJECT_NAME}_INCLUDE_DIRS}>"
"$<INSTALL_INTERFACE:${CMAKE_PROJECT_NAME}/include>")
if(CUDAToolkit_FOUND)
target_link_libraries(${PROJECT_NAME} PRIVATE pybind11::headers CUDA::cudart_static)
target_link_libraries(${PROJECT_NAME} PRIVATE CUDA::cudart_static)
else()
set_source_files_properties(${SRC} PROPERTIES LANGUAGE CXX)
target_link_libraries(${PROJECT_NAME} PRIVATE pybind11::headers)
endif()

set_target_properties(${PROJECT_NAME} PROPERTIES
Expand Down
2 changes: 1 addition & 1 deletion cuvec/src/example_pybind11/example_pybind11.cu
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* Copyright (2021) Casper da Costa-Luis
*/
#include "cuvec_pybind11.cuh" // NDCuVec
#include "cuvec.cuh" // NDCuVec
#include <pybind11/pybind11.h> // pybind11, PYBIND11_MODULE
#include <stdexcept> // std::length_error
#ifdef CUVEC_DISABLE_CUDA
Expand Down
6 changes: 3 additions & 3 deletions cuvec/src/example_swig/example_swig.cu
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*
* Copyright (2021) Casper da Costa-Luis
*/
#include "cuvec.cuh" // SwigCuVec, SwigCuVec_new
#include "cuvec.cuh" // NDCuVec
#include <stdexcept> // std::length_error
#ifdef CUVEC_DISABLE_CUDA
#include <chrono> // std::chrono
Expand All @@ -17,7 +17,7 @@ __global__ void _d_incr(float *dst, float *src, int X, int Y) {
dst[y * X + x] = src[y * X + x] + 1;
}
#endif // CUVEC_DISABLE_CUDA
SwigCuVec<float> *increment2d_f(SwigCuVec<float> &src, SwigCuVec<float> *output, bool timing) {
NDCuVec<float> *increment2d_f(NDCuVec<float> &src, NDCuVec<float> *output, bool timing) {
auto &N = src.shape;
if (N.size() != 2) throw std::length_error("`src` must be 2D");

Expand All @@ -32,7 +32,7 @@ SwigCuVec<float> *increment2d_f(SwigCuVec<float> &src, SwigCuVec<float> *output,
#endif

if (!output)
output = SwigCuVec_new<float>(N);
output = new NDCuVec<float>(N);
else if (N != output->shape)
throw std::length_error("`output` must be same shape as `src`");

Expand Down
6 changes: 3 additions & 3 deletions cuvec/src/example_swig/example_swig.i
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
}
}

%include "cuvec.i" // SwigCuVec<T>
%include "cuvec.i" // NDCuVec<T>
%{
/// signatures from "example_swig.cu"
SwigCuVec<float> *increment2d_f(SwigCuVec<float> &src, SwigCuVec<float> *output = NULL, bool timing = false);
NDCuVec<float> *increment2d_f(NDCuVec<float> &src, NDCuVec<float> *output = NULL, bool timing = false);
%}
/// expose definitions
SwigCuVec<float> *increment2d_f(SwigCuVec<float> &src, SwigCuVec<float> *output = NULL, bool timing = false);
NDCuVec<float> *increment2d_f(NDCuVec<float> &src, NDCuVec<float> *output = NULL, bool timing = false);
1 change: 1 addition & 0 deletions cuvec/src/pybind11.cu
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
PYBIND11_MODULE(cuvec_pybind11, m) {
m.doc() = "PyBind11 external module.";
pybind11::bind_vector<std::vector<size_t>>(m, "Shape");
pybind11::implicitly_convertible<pybind11::tuple, std::vector<size_t>>();
PYBIND11_BIND_NDCUVEC(signed char, b);
PYBIND11_BIND_NDCUVEC(unsigned char, B);
PYBIND11_BIND_NDCUVEC(char, c);
Expand Down

0 comments on commit b9a12bd

Please sign in to comment.