Skip to content

Commit

Permalink
Add buffer_protocol example and test
Browse files Browse the repository at this point in the history
  • Loading branch information
kkrissian-gpfw committed Sep 16, 2022
1 parent 14c5ef8 commit cd9b8b3
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 0 deletions.
66 changes: 66 additions & 0 deletions new_features/buffer_protocol/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)

PROJECT(BufferProtocolTest CXX)

FIND_PACKAGE(pybind11 CONFIG REQUIRED)

SET(BINDING_PREFIX binding CACHE STRING "Binding subfolder name")

# list of headers
SET(HDR buffer_protocol.hpp)
# list of source files
SET(SRC )

FIND_PROGRAM( BINDER binder HINTS ${CMAKE_CURRENT_SOURCE_DIR}/../../_build/source )

SET(BINDING_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${BINDING_PREFIX})

SET( BINDING_CONFIG ${CMAKE_CURRENT_SOURCE_DIR}/binding.cfg CACHE FILEPATH "Binding config file")
SET( BINDING_INCLUDE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/includes.hpp CACHE FILEPATH "Binding include file")

# Reconfigure if any of the listed files is modified
SET_PROPERTY( DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
${BINDER}
${BINDING_CONFIG}
${BINDING_INCLUDE_FILE}
${HDR}
${BINDING_PATH}
)

# Run binder and generate binding files
EXECUTE_PROCESS(
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${CMAKE_COMMAND} -E make_directory ${BINDING_PREFIX}
COMMAND ${BINDER} -root-module ${CMAKE_PROJECT_NAME} --prefix ${BINDING_PREFIX}
--config ${BINDING_CONFIG} ${BINDING_INCLUDE_FILE} -- -std=c++17 -fPIC -fpermissive -I${CMAKE_CURRENT_SOURCE_DIR}
COMMAND_ECHO STDOUT
OUTPUT_FILE ${CMAKE_PROJECT_NAME}.binder.out
ERROR_FILE ${CMAKE_PROJECT_NAME}.binder.log
RESULT_VARIABLE res
)

IF(NOT res EQUAL "0")
MESSAGE( FATAL_ERROR "Binder command line failed, logs in ${CMAKE_PROJECT_NAME}.binder.log")
ENDIF()


IF(EXISTS "${BINDING_PATH}/${CMAKE_PROJECT_NAME}.sources")
file(STRINGS ${BINDING_PATH}/${CMAKE_PROJECT_NAME}.sources BIND_SRC)
list(TRANSFORM BIND_SRC PREPEND "${BINDING_PREFIX}/")
MESSAGE(STATUS "BIND_SRC = ${BIND_SRC}")
ENDIF()

INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
${pybind11_INCLUDE_DIRS}
)

ADD_LIBRARY(${CMAKE_PROJECT_NAME} SHARED ${SRC} ${BIND_SRC} ${BINDING_INCLUDE_FILE} )

# Don't add lib prefix
SET_TARGET_PROPERTIES(${CMAKE_PROJECT_NAME} PROPERTIES PREFIX "")
SET_TARGET_PROPERTIES(${CMAKE_PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX)

# Compilation flags
TARGET_COMPILE_OPTIONS(${CMAKE_PROJECT_NAME} PRIVATE -w -std=c++17 -fPIC -fpermissive)

19 changes: 19 additions & 0 deletions new_features/buffer_protocol/addon_Matrix.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "buffer_protocol.hpp"
#include <pybind11/pybind11.h>
namespace py = pybind11;

template<class T>
void addon_Matrix(T &c)
{
c.def_buffer([](buffer_protocol_example::Matrix &m) -> py::buffer_info {
return py::buffer_info(
m.data(), /* Pointer to buffer */
sizeof(float), /* Size of one scalar */
py::format_descriptor<float>::format(), /* Python struct-style format descriptor */
2, /* Number of dimensions */
{ m.rows(), m.cols() }, /* Buffer dimensions */
{ sizeof(float) * m.cols(), /* Strides (in bytes) for each index */
sizeof(float) }
);
});
}
7 changes: 7 additions & 0 deletions new_features/buffer_protocol/binding.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#
+namespace buffer_protocol_example

# --- class
+buffer_protocol buffer_protocol_example::Matrix
+include_for_class buffer_protocol_example::Matrix "addon_Matrix.hpp"
+add_on_binder buffer_protocol_example::Matrix addon_Matrix
23 changes: 23 additions & 0 deletions new_features/buffer_protocol/buffer_protocol.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

#pragma once

namespace buffer_protocol_example {

class Matrix {
public:
Matrix(int rows, int cols) : m_rows(rows), m_cols(cols) {
m_data = new float[rows*cols];
for(int i =0; i<rows*cols; i++) m_data[i] = 0;
}
float get(int i, int j) { return m_data[i*m_cols+j];}
float *data() { return m_data; }
int rows() const { return m_rows; }
int cols() const { return m_cols; }
private:
int m_rows, m_cols;
float *m_data;
};

}


8 changes: 8 additions & 0 deletions new_features/buffer_protocol/buffer_protocol.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

from _build import BufferProtocolTest
import numpy as np
m = BufferProtocolTest.buffer_protocol_example.Matrix(3,2)
m1 = np.array(m, copy=False)
m1[2,1] = 4
assert m1[2,1] == m.get(2,1), "Failure: error in sharing data/buffer protocol for Matrix()"
print("Success: Buffer protocol is working for Matrix class")
2 changes: 2 additions & 0 deletions new_features/buffer_protocol/includes.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

#include <buffer_protocol.hpp>

0 comments on commit cd9b8b3

Please sign in to comment.