Skip to content
Open
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
23 changes: 2 additions & 21 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,24 +1,5 @@
*.lo
*.la
.vscode/
build/
*.o
*.so
.deps
.libs
aclocal.m4
autom4te.cache
configure
Makefile
Makefile.in
INSTALL
m4
py-compile
config.*
src/psftest
test/test_psfdataset
missing
ltmain.sh
libtool
libpsf.pc
libpsf-uninstalled.pc
depcomp
*~
25 changes: 25 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# https://stackoverflow.com/questions/17511496/how-to-create-a-shared-library-with-cmake
# https://github.com/giuliopaci/cmake-tutorial/blob/master/CMakeLists.txt

cmake_minimum_required(VERSION 3.12)

project(libpsf VERSION 0.3
DESCRIPTION "Load Cadence Spectre PSF simulation data"
LANGUAGES CXX)

option(WITH_PYTHON "Build python bindings" ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
include(CTest)
endif()

add_subdirectory(src)
add_subdirectory(test)

if(WITH_PYTHON)
add_subdirectory(bindings)
endif()
Empty file removed ChangeLog
Empty file.
14 changes: 0 additions & 14 deletions Makefile.am

This file was deleted.

Empty file removed NEWS
Empty file.
46 changes: 28 additions & 18 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,44 @@ libpsf is a c++ library that reads Cadence PSF waveform files
Install
=======

Install prerequisits
Install prerequisites
--------------------
If building without python binding, only cmake and boost are required

On a debian based system you can run the following to install the
- On a debian based system you can run the following to install the
packages needed to build libpsf:

sudo apt-get install autoconf automake libtool libboost-all-dev python-numpy-dev
$ sudo apt-get install cmake libboost-all-dev python-numpy-dev cython cppunit

- Otherwise conda can be used to install the following packages:

$ conda install python numpy cython cmake

Then install boost libraries and set

$ export BOOST_LOC=<BOOST_LOCATION>

Build and install
-----------------
To build and install the library::
- From root directory, create build directory

./autogen.sh
make
sudo make install
$ mkdir build && cd build
- Run cmake configuration

To build the python extension::
$ cmake .. -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DCMAKE_BUILD_TYPE=RELEASE -DWITH_PYTHON=ON

./autogen.sh --with-python
make
sudo make install
`CONDA_PREFIX` is the destination where you want libpsf to be installed
To build without the python binding, just set `-DWITH_PYTHON=OFF`
- Build

$ make
- To run tests, [cppunit](https://www.freedesktop.org/wiki/Software/cppunit) is required.

$ ctest

Running the tests
-----------------
Install cppunit, then compile and run the tests in the test dir::
`ctest --verbose` to see individual test result outputs

- Install

sudo apt-get install libcppunit-dev
cd test
make
./test_psfdataset
$ make install

6 changes: 0 additions & 6 deletions autogen.sh

This file was deleted.

1 change: 1 addition & 0 deletions bindings/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(python)
6 changes: 0 additions & 6 deletions bindings/Makefile.am

This file was deleted.

3 changes: 3 additions & 0 deletions bindings/python/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
libpsf.cpp
libpsf.h
*.pyc
46 changes: 46 additions & 0 deletions bindings/python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
find_package(Python COMPONENTS Interpreter Development)
find_program(CYTHON_EXECUTABLE NAMES cython cython3
HINTS ${_python_path})
# find_program(Python REQUIRED COMPONENTS Interpreter Development NumPy)
# https://bloerg.net/posts/cmake-and-distutils/
if( Python_EXECUTABLE AND CYTHON_EXECUTABLE)
MESSAGE( STATUS "numpy headers found at: ${Python_NumPy_INCLUDE_DIRS}")
MESSAGE( STATUS "cython found at: ${CYTHON_EXECUTABLE}")

# set variables for setup.py.in
get_target_property(LIBPSF_BUILD_DIR psf BINARY_DIR)
get_target_property(LIBPSF_INCLUDE psf INCLUDE_DIRECTORIES)

set(SETUP_PY_IN "${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in")
set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py")
set(DEPS setup.py.in psfpython.h psfpython.cc libpsf.pyx cpp_defs.pxd)
set(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build/timestamp")
configure_file(${SETUP_PY_IN} ${SETUP_PY})
# build commands
add_custom_command(OUTPUT ${OUTPUT}
COMMAND ${Python_EXECUTABLE} ${SETUP_PY} build_ext --inplace
COMMAND ${Python_EXECUTABLE} ${SETUP_PY} bdist_wheel
COMMAND ${CMAKE_COMMAND} -E touch ${OUTPUT}
DEPENDS ${DEPS})

add_custom_target(python_binding ALL DEPENDS ${OUTPUT})
add_dependencies(python_binding psf)
# install binding
install(CODE "execute_process(COMMAND ${Python_EXECUTABLE} ${SETUP_PY} install)")


install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/dist
DESTINATION ${CMAKE_CURRENT_SOURCE_DIR})

# tests
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
add_test(NAME python_test
COMMAND ${Python_EXECUTABLE} -m unittest test_psfdataset.py -v
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/tests")
set_tests_properties(python_test PROPERTIES
ENVIRONMENT PYTHONPATH=${CMAKE_CURRENT_BINARY_DIR}:$ENV{PYTHONPATH})
endif()

else()
MESSAGE( WARNING "python/numpy/cython include not found, skipping python bindings")
endif()
17 changes: 0 additions & 17 deletions bindings/python/Makefile.am

This file was deleted.

1 change: 0 additions & 1 deletion bindings/python/__init__.py

This file was deleted.

33 changes: 33 additions & 0 deletions bindings/python/cpp_defs.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# https://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html
# https://stackoverflow.com/a/10121232
# https://stackoverflow.com/a/29002414
from cpython.ref cimport PyObject

from libcpp cimport bool
from libcpp.string cimport string
from libcpp.vector cimport vector

cdef extern from "psf.h":
cdef cppclass PSFVector
cdef cppclass PSFBase

cdef extern from "psfpython.h":
cdef void raise_py_error()
cdef cppclass PropertyMap

cdef extern from "psf.h":
cdef cppclass PSFDataSet:
PSFDataSet(string) except +raise_py_error
int get_nsweeps() except +raise_py_error
int get_sweep_npoints() except +raise_py_error
const vector[string] get_signal_names() except +raise_py_error
const vector[string] get_sweep_param_names() except +raise_py_error
PSFVector* get_sweep_values() except +raise_py_error
PSFBase *get_signal(string name) except +raise_py_error
PropertyMap& get_signal_properties(string name) except +raise_py_error
PropertyMap& get_header_properties() except +raise_py_error
bool is_swept() except +raise_py_error
void close() except +raise_py_error
void open() except +raise_py_error
void set_invertstruct(bool value) except +raise_py_error
bool get_invertstruct() except +raise_py_error
Binary file not shown.
110 changes: 110 additions & 0 deletions bindings/python/libpsf.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# distutils: language = c++
# cython: language_level=2

from libcpp cimport bool

from cpython.ref cimport PyObject
from cpp_defs cimport PSFVector, PSFBase, PropertyMap
from cpp_defs cimport PSFDataSet as C_PSFDataSet

cimport numpy as np
np.import_array()

cdef extern from "psfpython.h":
cdef np.ndarray psfvector_to_numpy_array(PSFVector *vec, bool copy)
cdef object psfbase_to_numpy_array(PSFBase *d)
cdef object propertymap_to_python(PropertyMap& propmap)

class FileOpenError(RuntimeError):
pass

class NotFound(RuntimeError):
pass

class DataSetNotOpen(RuntimeError):
pass

class UnknownType(RuntimeError):
pass

class IncorrectChunk(RuntimeError):
pass

cdef public PyObject* fileOpenError = <PyObject*>FileOpenError
cdef public PyObject* notFoundError = <PyObject*>NotFound
cdef public PyObject* notOpenError = <PyObject*>DataSetNotOpen
cdef public PyObject* unknownTypeError = <PyObject*>UnknownType
cdef public PyObject* incorrectChunkError = <PyObject*>IncorrectChunk


cdef to_unicode(str_):
return str_.encode('UTF-8')

cdef bytes_to_string(str_list):
return map(lambda x: x.decode('UTF-8'), str_list)


cdef class PSFDataSet:
cdef C_PSFDataSet *obj

def __cinit__(self, filename):
self.obj = new C_PSFDataSet(to_unicode(filename))

def __dealloc__(self):
del self.obj

def get_nsweeps(self):
"""Return the number of sweeps"""
return self.obj.get_nsweeps()

def get_sweep_npoints(self):
"""Return the number of points in the sweep"""
return self.obj.get_sweep_npoints()

def get_signal_names(self):
"""Return a list of signal names"""
return bytes_to_string(self.obj.get_signal_names())

def get_sweep_param_names(self):
"""Parameters that have been swept"""
return bytes_to_string(self.obj.get_sweep_param_names())

def get_sweep_values(self):
"""Numpy array of swept values"""
return psfvector_to_numpy_array(self.obj.get_sweep_values(), False)

def get_signal(self, signal):
"""Numpy array of signal values"""
return psfbase_to_numpy_array(self.obj.get_signal(to_unicode(signal)))

def get_signal_properties(self, signal):
"""Properties of a non swept signal
Throws NotFound exception for non_swept datasets so check self.is_swept
first
"""
return propertymap_to_python(self.obj.get_signal_properties(to_unicode(signal)))

def get_header_properties(self):
"""Dict of header [rp[ertoes and values"""
return propertymap_to_python(self.obj.get_header_properties())

def is_swept(self):
"""Is the data swept"""
return self.obj.is_swept()

def close(self):
"""Close PSF Data Set"""
self.obj.close()

def open(self):
"""Open PSF Data Set"""
self.obj.open()

def set_invertstruct(self, bool value):
"""Set invert struct"""
self.obj.set_invertstruct(value)

def get_invertstruct(self):
"""Get invert struct"""
return self.obj.get_invertstruct()

Loading