Skip to content
cuda.hpp 52.9 KiB
Newer Older
// A C++ wrapper for CUDA




#ifndef _AFJDFJSDFSD_PYCUDA_HEADER_SEEN_CUDA_HPP
#define _AFJDFJSDFSD_PYCUDA_HEADER_SEEN_CUDA_HPP




#include <cuda.h>

#ifdef CUDAPP_PRETEND_CUDA_VERSION
#define CUDAPP_CUDA_VERSION CUDAPP_PRETEND_CUDA_VERSION
#else
#define CUDAPP_CUDA_VERSION CUDA_VERSION
#endif

#if CUDAPP_CUDA_VERSION >= 4000
#include <cudaProfiler.h>
#endif

#ifndef _MSC_VER
#endif
#include <stdexcept>
#include <boost/shared_ptr.hpp>
#include <boost/foreach.hpp>
#include <stack>
#include <iostream>
#include <vector>
#include <boost/python.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/tss.hpp>
#include <boost/version.hpp>

#if (BOOST_VERSION/100) < 1035
#warning *****************************************************************
#warning **** Your version of Boost C++ is likely too old for PyCUDA. ****
#warning *****************************************************************
#endif
// MAYBE? cuMemcpy, cuPointerGetAttribute
// TODO: cuCtxSetCurrent, cuCtxGetCurrent 
// (use once the old, deprecated functions have been removed from CUDA)
// #define CUDAPP_TRACE_CUDA
#define CUDAPP_POST_30_BETA
#ifdef CUDAPP_PRETEND_CUDA_VERSION
#define CUDAPP_CUDA_VERSION CUDAPP_PRETEND_CUDA_VERSION
#else
#define CUDAPP_CUDA_VERSION CUDA_VERSION
#endif

#if PY_VERSION_HEX >= 0x02050000
  typedef Py_ssize_t PYCUDA_BUFFER_SIZE_T;
#else
  typedef int PYCUDA_BUFFER_SIZE_T;
#endif



#define PYCUDA_PARSE_STREAM_PY \
    CUstream s_handle; \
    if (stream_py.ptr() != Py_None) \
    { \
      const stream &s = py::extract<const stream &>(stream_py); \
      s_handle = s.handle(); \
    } \
    else \
      s_handle = 0;



// {{{ tracing and error guards

#ifdef CUDAPP_TRACE_CUDA
  #define CUDAPP_PRINT_CALL_TRACE(NAME) \
    std::cerr << NAME << std::endl;
  #define CUDAPP_PRINT_CALL_TRACE_INFO(NAME, EXTRA_INFO) \
    std::cerr << NAME << " (" << EXTRA_INFO << ')' << std::endl;
  #define CUDAPP_PRINT_ERROR_TRACE(NAME, CODE) \
    if (CODE != CUDA_SUCCESS) \
      std::cerr << NAME << " failed with code " << CODE << std::endl;
#else
  #define CUDAPP_PRINT_CALL_TRACE(NAME) /*nothing*/
  #define CUDAPP_PRINT_CALL_TRACE_INFO(NAME, EXTRA_INFO) /*nothing*/
  #define CUDAPP_PRINT_ERROR_TRACE(NAME, CODE) /*nothing*/
#define CUDAPP_CALL_GUARDED_THREADED_WITH_TRACE_INFO(NAME, ARGLIST, TRACE_INFO) \
  { \
    CUDAPP_PRINT_CALL_TRACE_INFO(#NAME, TRACE_INFO); \
    CUresult cu_status_code; \
    Py_BEGIN_ALLOW_THREADS \
      cu_status_code = NAME ARGLIST; \
    Py_END_ALLOW_THREADS \
    if (cu_status_code != CUDA_SUCCESS) \
      throw pycuda::error(#NAME, cu_status_code);\
  }

#define CUDAPP_CALL_GUARDED_WITH_TRACE_INFO(NAME, ARGLIST, TRACE_INFO) \
  { \
    CUDAPP_PRINT_CALL_TRACE_INFO(#NAME, TRACE_INFO); \
    CUresult cu_status_code; \
    cu_status_code = NAME ARGLIST; \
    CUDAPP_PRINT_ERROR_TRACE(#NAME, cu_status_code); \
    if (cu_status_code != CUDA_SUCCESS) \
      throw pycuda::error(#NAME, cu_status_code);\
#define CUDAPP_CALL_GUARDED_THREADED(NAME, ARGLIST) \
    CUDAPP_PRINT_CALL_TRACE(#NAME); \
    CUresult cu_status_code; \
    Py_BEGIN_ALLOW_THREADS \
      cu_status_code = NAME ARGLIST; \
    Py_END_ALLOW_THREADS \
    CUDAPP_PRINT_ERROR_TRACE(#NAME, cu_status_code); \
    if (cu_status_code != CUDA_SUCCESS) \
      throw pycuda::error(#NAME, cu_status_code);\
#define CUDAPP_CALL_GUARDED(NAME, ARGLIST) \
  { \
    CUDAPP_PRINT_CALL_TRACE(#NAME); \
    CUresult cu_status_code; \
    cu_status_code = NAME ARGLIST; \
    CUDAPP_PRINT_ERROR_TRACE(#NAME, cu_status_code); \
    if (cu_status_code != CUDA_SUCCESS) \
      throw pycuda::error(#NAME, cu_status_code);\
#define CUDAPP_CALL_GUARDED_CLEANUP(NAME, ARGLIST) \
  { \
    CUDAPP_PRINT_CALL_TRACE(#NAME); \
    CUresult cu_status_code; \
    cu_status_code = NAME ARGLIST; \
    CUDAPP_PRINT_ERROR_TRACE(#NAME, cu_status_code); \
    if (cu_status_code != CUDA_SUCCESS) \
      std::cerr \
        << "PyCUDA WARNING: a clean-up operation failed (dead context maybe?)" \
        << std::endl \
        << pycuda::error::make_message(#NAME, cu_status_code) \
#define CUDAPP_CATCH_CLEANUP_ON_DEAD_CONTEXT(TYPE) \
  catch (pycuda::cannot_activate_out_of_thread_context) \
  catch (pycuda::cannot_activate_dead_context) \
  { \
    /* PyErr_Warn( \
        PyExc_UserWarning, #TYPE " in dead context was implicitly cleaned up");*/ \
  }
  // In all likelihood, this TYPE's managing thread has exited, and
  // therefore its context has already been deleted. No need to harp
  // on the fact that we still thought there was cleanup to do.

  typedef
        size_t
#else
        unsigned int 
#endif
        pycuda_size_t;
  typedef 
#if defined(_WIN32) && defined(_WIN64)
    long long
#else
    long
#endif
    hash_type;

  // {{{ error reporting
  class error : public std::runtime_error
  {
    private:
      const char *m_routine;
      CUresult m_code;

Loading
Loading full blame...