Skip to content

Commit

Permalink
Merge pull request #16 from odlgroup/make_plugin
Browse files Browse the repository at this point in the history
Make plugin
  • Loading branch information
adler-j authored Jun 30, 2016
2 parents 8e98143 + 7e6c4b5 commit 06e80b8
Show file tree
Hide file tree
Showing 27 changed files with 2,834 additions and 74 deletions.
11 changes: 6 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
cmake_minimum_required (VERSION 2.6)

project (odlpp)
project (odlcuda)

if(NOT EXISTS "${CMAKE_SOURCE_DIR}/odl_cpp_utils/CMakeLists.txt")
message(FATAL_ERROR "odl_cpp_utils not initialized. Run 'git submodule update --init'." )
endif()

#Set binary dir
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
Expand Down Expand Up @@ -92,8 +96,5 @@ include_directories(${PYTHON_NUMPY_INCLUDE_DIR})
link_directories(${PYTHON_LIBRARIES})

# Add sub directories as needed
add_subdirectory (odlpp)
if(NOT EXISTS "${CMAKE_SOURCE_DIR}/odl_cpp_utils/CMakeLists.txt")
message(SEND_ERROR "odl_cpp_utils not initialized. Run 'git submodule update --init'." )
endif()
add_subdirectory (odlcuda)
add_subdirectory (odl_cpp_utils)
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
ODLpp
=====
odlcuda
=======

C++ backend for ODL
CUDA backend for [ODL](https://github.com/odlgroup/odl)

Introduction
--------------------
This is a default backend for ODL, intended to contain examples of ODL interactions with C++.
------------
This is a default CUDA backend for ODL. It contains a default implementation of a CUDA based Rn space with associated methods.

It contains a default implementation of a CUDA based Rn space with associated methods.
By installing this package, CUDA spaces become available to `rn`, `uniform_discr` and related spaces in ODL through the `impl='cuda'` option.

Building
--------------------
--------
The project uses CMake to enable builds. Using *cmake-gui* is recommended

[Cmake webpage](http://www.cmake.org/)
Expand All @@ -28,7 +28,7 @@ To build and install the package to your python installation, run (as root)

make pyinstall

To verify your installation, run (in the odlpp root directory)
To verify your installation, run (in the odlcuda root directory)

py.test

Expand Down Expand Up @@ -62,7 +62,7 @@ External Dependences
Current external dependencies are

#####Python
The building block of ODL, ODLpp needs access to both python and numpy header files and compiled files to link against.
The building block of ODL, odlcuda needs access to both python and numpy header files and compiled files to link against.

#####Boost
General library with C++ code. This project specifically uses [Boost.Python](http://www.boost.org/doc/libs/1_58_0/libs/python/doc/index.html) to handle the python bindings.
Expand Down Expand Up @@ -95,20 +95,20 @@ There are a few common errors encountered, this is the solution to some of these

* Compiling

[ 20%] Building NVCC (Device) object ODLpp/CMakeFiles/cuda.dir//./cuda_generated_cuda.cu.o /usr/include/c++/4.9.2/bits/alloc_traits.h(248): error: expected a ">"
[ 20%] Building NVCC (Device) object odlcuda/CMakeFiles/cuda.dir//./cuda_generated_cuda.cu.o /usr/include/c++/4.9.2/bits/alloc_traits.h(248): error: expected a ">"

It may be that you are trying to compile with CUDA 6.5 and GCC 4.9, this combination is not supported by CUDA.

* Compiling

error LNK1112: module machine type 'x64' conflicts with target machine type 'X86'

You have a 64-bit library on your path (Boost for instance) while trying to build 32-bit odlpp. Either change the lib, or configure to build 64-bit. On Windows, if you are using Visual Studio to compile use Configuration Manager to set platform to x64, if you are compiling on command line via CMake ensure that the Script Generator is for instance "Visual Studio 12 2013 Win64" (note the Win64 at the end).
You have a 64-bit library on your path (Boost for instance) while trying to build 32-bit odlcuda. Either change the lib, or configure to build 64-bit. On Windows, if you are using Visual Studio to compile use Configuration Manager to set platform to x64, if you are compiling on command line via CMake ensure that the Script Generator is for instance "Visual Studio 12 2013 Win64" (note the Win64 at the end).


* If you get a error like

Error 5 error LNK2019: unresolved external symbol "__declspec(dllimport) struct _object * __cdecl boost::python::detail::init_module(struct PyModuleDef &,void (__cdecl*)(void))" (__imp_?init_module@detail@python@boost@@YAPEAU_object@@AEAUPyModuleDef@@P6AXXZ@Z) referenced in function PyInit_utils C:\Programming\Projects\ODLpp_bin\RLcpp\utils.obj utils
Error 5 error LNK2019: unresolved external symbol "__declspec(dllimport) struct _object * __cdecl boost::python::detail::init_module(struct PyModuleDef &,void (__cdecl*)(void))" (__imp_?init_module@detail@python@boost@@YAPEAU_object@@AEAUPyModuleDef@@P6AXXZ@Z) referenced in function PyInit_utils C:\Programming\Projects\odlcuda_bin\odlcuda\utils.obj utils

then it is likely that you are trying to build against unmatched python header files and boost python version

Expand All @@ -122,7 +122,7 @@ There are a few common errors encountered, this is the solution to some of these

* If, when running the test in python, you encounter an error like

ImportError: No module named odlpp
ImportError: No module named odlcuda

It may be that you have not installed the package, run (as root) `make pyinstall` or equivalent.

Expand Down
82 changes: 82 additions & 0 deletions examples/cudaspace_speedtest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Copyright 2014-2016 The ODL development group
#
# This file is part of ODL.
#
# ODL is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ODL is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with ODL. If not, see <http://www.gnu.org/licenses/>.

"""Speed comparison between CPU and GPU spaces."""

# Imports for common Python 2/3 codebase
from __future__ import print_function, division, absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import range

import numpy as np
import odl
from odl.util.testutils import Timer

n = 10**7
iterations = 100
device_space = odl.CudaRn(n)
host_space = odl.Rn(n)
x = np.random.rand(n)
y = np.random.rand(n)
z = np.empty(n)

x_dev = device_space.element(x)
y_dev = device_space.element(y)
z_dev = device_space.element(z)
x_host = host_space.element(x)
y_host = host_space.element(y)
z_host = host_space.element(z)


def run_test(function, message):
with Timer('+GPU ' + message):
for _ in range(iterations):
function(z_dev, x_dev, y_dev)

with Timer('-CPU ' + message):
for _ in range(iterations):
function(z_host, x_host, y_host)

# lincomb tests
run_test(lambda z, x, y: x.space.lincomb(0, x, 0, y, z), "z = 0")
run_test(lambda z, x, y: x.space.lincomb(0, x, 1, y, z), "z = y")
run_test(lambda z, x, y: x.space.lincomb(0, x, 2, y, z), "z = b*y")

run_test(lambda z, x, y: x.space.lincomb(1, x, 0, y, z), "z = x")
run_test(lambda z, x, y: x.space.lincomb(1, x, 1, y, z), "z = x + y")
run_test(lambda z, x, y: x.space.lincomb(1, x, 2, y, z), "z = x + b*y")

run_test(lambda z, x, y: x.space.lincomb(2, x, 0, y, z), "z = a*x")
run_test(lambda z, x, y: x.space.lincomb(2, x, 1, y, z), "z = a*x + y")
run_test(lambda z, x, y: x.space.lincomb(2, x, 2, y, z), "z = a*x + b*y")

# Test optimization for 1 aliased vector
run_test(lambda z, x, y: x.space.lincomb(1, z, 0, y, z), "z = z")
run_test(lambda z, x, y: x.space.lincomb(1, z, 1, y, z), "z += y")
run_test(lambda z, x, y: x.space.lincomb(1, z, 2, y, z), "z += b*y")

run_test(lambda z, x, y: x.space.lincomb(2, z, 0, y, z), "z = a*z")
run_test(lambda z, x, y: x.space.lincomb(2, z, 1, y, z), "z = a*z + y")
run_test(lambda z, x, y: x.space.lincomb(2, z, 2, y, z), "z = a*z + b*y")

# Test optimization for 2 aliased vectors
run_test(lambda z, x, y: x.space.lincomb(2, z, 2, z, z), "z = (a+b)*z")

# Non lincomb tests
run_test(lambda z, x, y: x + y, "z = x + y")
run_test(lambda z, x, y: y.assign(x), "y.assign(x)")
12 changes: 9 additions & 3 deletions odlpp/CMakeLists.txt → odlcuda/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,25 @@ else(WIN32)
endif(WIN32)

if(CUDA_ENABLED)
set(PYTHON_LIBS ${PYTHON_LIBS} "odlpp_cuda")
set(PYTHON_LIBS ${PYTHON_LIBS} "odlcuda_")
endif(CUDA_ENABLED)

set(INSTALL_LIB "pyinstall")
add_custom_target(${INSTALL_LIB} COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/__init__.py ${TARGET_PY}/__init__.py)
set_property(TARGET ${INSTALL_LIB} PROPERTY FOLDER python)

# do the copying
# copy raw python files
set(python_files odl_plugin.py setup.py cu_ntuples.py ufuncs.py)
foreach(file_i ${python_files})
add_custom_command(TARGET ${INSTALL_LIB} COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${file_i} ${TARGET_PY}/${file_i})
endforeach()

# copy compiled files
foreach(file_i ${PYTHON_LIBS})
add_custom_command(TARGET ${INSTALL_LIB} COMMAND ${CMAKE_COMMAND} -E copy ${TARGET_PY}/${FILESTART}${file_i}.${FILETYPE} ${TARGET_PY}/${file_i}.${TARGETFILETYPE})
endforeach()

add_custom_command(TARGET ${INSTALL_LIB} COMMAND cd ${TARGET_PY} && ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/setup.py install)
add_custom_command(TARGET ${INSTALL_LIB} COMMAND cd ${TARGET_PY} && ${PYTHON_EXECUTABLE} setup.py install)

add_dependencies(${INSTALL_LIB} ${PYTHON_LIBS})

Expand Down
9 changes: 6 additions & 3 deletions odlpp/__init__.py → odlcuda/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2014, 2015 The ODL development group
# Copyright 2014-2016 The ODL development group
#
# This file is part of ODL.
#
Expand All @@ -17,6 +17,9 @@

from __future__ import absolute_import

from . import odlpp_cuda
# Workaround for weird bug. Nothing is installed without this
_install_location = __file__

# __all__ = ['']
from . import odlcuda_
from . import cu_ntuples
from . import ufuncs
Loading

0 comments on commit 06e80b8

Please sign in to comment.