Skip to content
Snippets Groups Projects
Commit b33f7e1b authored by Mark Winter's avatar Mark Winter
Browse files

Moved script-array helper routines into common code and namespace with define guards

parent a9209a94
No related branches found
No related tags found
No related merge requests found
......@@ -55,6 +55,7 @@
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(MATLAB_DIR)\extern\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WINDLL;_CRT_SECURE_NO_WARNINGS;_CRTDBG_MAP_ALLOC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessToFile>false</PreprocessToFile>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
......@@ -76,6 +77,7 @@ copy $(OutDir)CudaMex.dll "$(ProjectDir)Mex.mexw64"</Command>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(MATLAB_DIR)\extern\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessToFile>false</PreprocessToFile>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
......@@ -93,9 +95,12 @@ copy $(OutDir)CudaMex.dll "$(ProjectDir)Mex.mexw64"</Command>
<ItemGroup>
<ClInclude Include="Cuda\Vec.h" />
<ClInclude Include="Mex\MexCommand.h" />
<ClInclude Include="Mex\MexTypes.h" />
<ClInclude Include="Mex\MexIncludes.h" />
<ClInclude Include="Mex\MexWrapDef.h" />
<ClInclude Include="Mex\MexKernel.h" />
<ClInclude Include="WrapCmds\CommandList.h" />
<ClInclude Include="WrapCmds\ScriptHelpers.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Mex\CudaMex.cpp" />
......
......@@ -30,6 +30,15 @@
<ClInclude Include="Mex\MexWrapDef.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Mex\MexIncludes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Mex\MexTypes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WrapCmds\ScriptHelpers.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Mex\CudaMex.cpp">
......
......@@ -46,8 +46,10 @@
<ItemGroup>
<ClInclude Include="Python\PyIncludes.h" />
<ClInclude Include="Python\PyKernel.h" />
<ClInclude Include="Python\PyTypes.h" />
<ClInclude Include="Python\PyWrapCommand.h" />
<ClInclude Include="Python\PyWrapDef.h" />
<ClInclude Include="WrapCmds\ScriptHelpers.h" />
<ClInclude Include="WrapCmds\CommandList.h" />
</ItemGroup>
<PropertyGroup Label="Globals">
......
......@@ -101,5 +101,11 @@
<ClInclude Include="Python\PyIncludes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WrapCmds\ScriptHelpers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Python\PyTypes.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -141,25 +141,6 @@ void MexHelp::help(std::vector<std::string>& helpLines) const
helpLines.push_back("Print detailed usage information for the specified command.");
}
void MexCommand::setupDims(const mxArray* im, ImageDimensions& dimsOut)
{
dimsOut.dims = Vec<std::size_t>(1);
dimsOut.chan = 1;
dimsOut.frame = 1;
std::size_t numDims = mxGetNumberOfDimensions(im);
const mwSize* DIMS = mxGetDimensions(im);
for ( int i=0; i < MIN(numDims,3); ++i )
dimsOut.dims.e[i] = (std::size_t)DIMS[i];
if (numDims > 3)
dimsOut.chan = (unsigned int)DIMS[3];
if (numDims > 4)
dimsOut.frame = (unsigned int)DIMS[4];
}
Vec<std::size_t> MexCommand::FillKernel(const mxArray* matKernelIn, float** kernel )
{
std::size_t numDims = mxGetNumberOfDimensions(matKernelIn);
......
......@@ -2,7 +2,7 @@
#include "../Cuda/Vec.h"
#include "../Cuda/ImageDimensions.cuh"
#include <mex.h>
#include "MexIncludes.h"
#include <cstring>
#include <vector>
......@@ -10,17 +10,6 @@
#include <algorithm>
#include <exception>
// Simple template-specialization map for C++ to mex types
template <typename T> struct TypeMap { static const mxClassID mxType; };
template <> struct TypeMap<char> { static const mxClassID mxType = mxINT8_CLASS; };
template <> struct TypeMap<short> { static const mxClassID mxType = mxINT16_CLASS; };
template <> struct TypeMap<int> { static const mxClassID mxType = mxINT32_CLASS; };
template <> struct TypeMap<unsigned char> { static const mxClassID mxType = mxUINT8_CLASS; };
template <> struct TypeMap<unsigned short> { static const mxClassID mxType = mxUINT16_CLASS; };
template <> struct TypeMap<unsigned int> { static const mxClassID mxType = mxUINT32_CLASS; };
template <> struct TypeMap<float> { static const mxClassID mxType = mxSINGLE_CLASS; };
template <> struct TypeMap<double> { static const mxClassID mxType = mxDOUBLE_CLASS; };
// Abstract base class for mex commands
class MexCommand
......@@ -174,55 +163,6 @@ protected:
return usageString;
}
// Helper function for MexCommands class
static void setupDims(const mxArray* im, ImageDimensions& dims);
// General array creation method
template <typename T>
static mxArray* createArray(mwSize ndim, const mwSize* dims)
{
return mxCreateNumericArray(ndim, dims, TypeMap<T>::mxType, mxREAL);
}
// Logical array creation specialization
template <>
static mxArray* createArray<bool>(mwSize ndim, const mwSize* dims)
{
return mxCreateLogicalArray(ndim, dims);
}
template <typename T>
static void setupImagePointers(const mxArray* imageIn, T** image, ImageDimensions& dims, mxArray** argOut = NULL, T** imageOut = NULL)
{
setupInputPointers(imageIn, dims, image);
if (argOut!=NULL && imageOut!=NULL)
setupOutputPointers(argOut, dims, imageOut);
}
template <typename T>
static void setupInputPointers(const mxArray* imageIn, ImageDimensions& pDims, T** image)
{
setupDims(imageIn, pDims);
*image = (T*)mxGetData(imageIn);
}
template <typename T>
static void setupOutputPointers(mxArray** imageOut, ImageDimensions& dims, T** image)
{
mwSize matDims[5];
for (int i = 0; i < 3; ++i)
matDims[i] = dims.dims.e[i];
matDims[3] = dims.chan;
matDims[4] = dims.frame;
*imageOut = createArray<T>(5, matDims);
*image = (T*)mxGetData(*imageOut);
std::memset(*image, 0, sizeof(T)*dims.getNumElements());
}
static Vec<std::size_t> MexCommand::FillKernel(const mxArray* matKernelIn, float** kernel);
private:
......
#pragma once
#include <mex.h>
#define MEX_BUILD
#include "../WrapCmds/ScriptHelpers.h"
#pragma once
#include <mex.h>
#include <cstddef>
namespace Script
{
typedef mwSize DimType;
typedef mxArray ArrayType;
typedef mxArray ObjectType;
// Simple template-specialization map for C++ to mex types
template <typename T> struct TypeMap {};
template <> struct TypeMap<bool> { static const mxClassID typeId = mxLOGICAL_CLASS; };
template <> struct TypeMap<char> { static const mxClassID typeId = mxINT8_CLASS; };
template <> struct TypeMap<short> { static const mxClassID typeId = mxINT16_CLASS; };
template <> struct TypeMap<int> { static const mxClassID typeId = mxINT32_CLASS; };
template <> struct TypeMap<unsigned char> { static const mxClassID typeId = mxUINT8_CLASS; };
template <> struct TypeMap<unsigned short> { static const mxClassID typeId = mxUINT16_CLASS; };
template <> struct TypeMap<unsigned int> { static const mxClassID typeId = mxUINT32_CLASS; };
template <> struct TypeMap<float> { static const mxClassID typeId = mxSINGLE_CLASS; };
template <> struct TypeMap<double> { static const mxClassID typeId = mxDOUBLE_CLASS; };
// Helper functions for array allocation
template <typename T>
ArrayType* createArray(int ndim, DimType* dims)
{
return mxCreateNumericArray(ndim, dims, TypeMap<T>::typeId, mxREAL);
}
template <>
inline ArrayType* createArray<bool>(int ndim, DimType* dims)
{
return mxCreateLogicalArray(ndim, dims);
}
namespace ArrayInfo
{
inline std::size_t getNDims(const ArrayType* im){ return mxGetNumberOfDimensions(im); }
inline const DimType* getDims(const ArrayType* im){ return mxGetDimensions(im); }
template <typename T>
T* getData(const ArrayType* im) { return (T*)mxGetData(im); }
};
};
#pragma once
#include <Python.h>
#define PY_BUILD
#include "../WrapCmds/ScriptHelpers.h"
// Make sure that Numpy symbols don't get re-imported in multiple compilation units
#ifndef NUMPY_IMPORT_MODULE
#define NO_IMPORT_ARRAY
#endif
#define PY_ARRAY_UNIQUE_SYMBOL HIP_ARRAY_API
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/arrayobject.h>
#include <py3c.h>
#pragma once
#include <Python.h>
// Make sure that Numpy symbols don't get re-imported in multiple compilation units
#ifndef NUMPY_IMPORT_MODULE
#define NO_IMPORT_ARRAY
#endif
#define PY_ARRAY_UNIQUE_SYMBOL HIP_ARRAY_API
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/arrayobject.h>
#include <py3c.h>
#include <cstddef>
namespace Script
{
typedef npy_intp DimType;
typedef PyObject ObjectType;
typedef PyArrayObject ArrayType;
// Simple template-specialization map for C++ to mex types
template <typename T> struct TypeMap { static const NPY_TYPES npyType; };
template <> struct TypeMap<bool> { static const NPY_TYPES npyType = NPY_BOOL; };
template <> struct TypeMap<char> { static const NPY_TYPES npyType = NPY_INT8; };
template <> struct TypeMap<short> { static const NPY_TYPES npyType = NPY_INT16; };
template <> struct TypeMap<int> { static const NPY_TYPES npyType = NPY_INT32; };
template <> struct TypeMap<unsigned char> { static const NPY_TYPES npyType = NPY_UINT8; };
template <> struct TypeMap<unsigned short> { static const NPY_TYPES npyType = NPY_UINT16; };
template <> struct TypeMap<unsigned int> { static const NPY_TYPES npyType = NPY_UINT32; };
template <> struct TypeMap<float> { static const NPY_TYPES npyType = NPY_FLOAT; };
template <> struct TypeMap<double> { static const NPY_TYPES npyType = NPY_DOUBLE; };
template <typename T> ArrayType* createArray(int ndim, DimType* dims)
{
return ((ArrayType*) PyArray_SimpleNew(ndim, dims, TypeMap<T>::npyType));
}
// TODO: Figure out if we can do this without the const-casting?
namespace ArrayInfo
{
inline std::size_t getNDims(const ArrayType* im) { return PyArray_NDIM(im); }
inline DimType* getDims(const ArrayType* im) { return PyArray_DIMS(const_cast<ArrayType*>(im)); }
template <typename T>
T* getData(const ArrayType* im) { return (T*) PyArray_DATA(const_cast<ArrayType*>(im)); }
};
// Some Python-specific converters
bool pyobjToVec(ObjectType* list_array, Vec<double>& outVec);
bool pylistToVec(ObjectType* list, Vec<double>& outVec);
bool pyarrayToVec(ArrayType* ar, Vec<double>& outVec);
};
......@@ -12,26 +12,6 @@
#undef BUILD_COMMANDS
void setupDims(PyArrayObject* im, ImageDimensions& dimsOut)
{
dimsOut.dims = Vec<std::size_t>(1);
dimsOut.chan = 1;
dimsOut.frame = 1;
int numDims = PyArray_NDIM(im);
const npy_intp* DIMS = PyArray_DIMS(im);
for ( int i=0; i < std::min(numDims, 3); ++i )
dimsOut.dims.e[i] = (std::size_t)DIMS[i];
if ( numDims > 3 )
dimsOut.chan = (unsigned int)DIMS[3];
if ( numDims > 4 )
dimsOut.frame = (unsigned int)DIMS[4];
}
template <typename T, typename U>
void converter(void* in, void* out, std::size_t len)
{
......@@ -39,7 +19,7 @@ void converter(void* in, void* out, std::size_t len)
((U*)out)[i] = static_cast<U>(((T*)in)[i]);
}
bool pyarrayToVec(PyArrayObject* ar, Vec<double>& outVec)
bool Script::pyarrayToVec(PyArrayObject* ar, Vec<double>& outVec)
{
int ndim = PyArray_NDIM(ar);
if ( ndim > 1 )
......@@ -68,7 +48,7 @@ bool pyarrayToVec(PyArrayObject* ar, Vec<double>& outVec)
}
bool pylistToVec(PyObject* list, Vec<double>& outVec)
bool Script::pylistToVec(PyObject* list, Vec<double>& outVec)
{
Py_ssize_t list_size = PyList_Size(list);
if ( list_size != 3 )
......@@ -89,7 +69,7 @@ bool pylistToVec(PyObject* list, Vec<double>& outVec)
}
bool pyobjToVec(PyObject* list_array, Vec<double>& outVec)
bool Script::pyobjToVec(PyObject* list_array, Vec<double>& outVec)
{
if ( PyList_Check(list_array) )
return pylistToVec(list_array, outVec);
......
......@@ -3,66 +3,7 @@
#include <cstring>
#include <algorithm>
#include "../Cuda/Vec.h"
#include "../Cuda/ImageDimensions.cuh"
#include "PyIncludes.h"
// Simple template-specialization map for C++ to mex types
template <typename T> struct TypeMap { static const NPY_TYPES npyType; };
template <> struct TypeMap<bool> { static const NPY_TYPES npyType = NPY_BOOL; };
template <> struct TypeMap<char> { static const NPY_TYPES npyType = NPY_INT8; };
template <> struct TypeMap<short> { static const NPY_TYPES npyType = NPY_INT16; };
template <> struct TypeMap<int> { static const NPY_TYPES npyType = NPY_INT32; };
template <> struct TypeMap<unsigned char> { static const NPY_TYPES npyType = NPY_UINT8; };
template <> struct TypeMap<unsigned short> { static const NPY_TYPES npyType = NPY_UINT16; };
template <> struct TypeMap<unsigned int> { static const NPY_TYPES npyType = NPY_UINT32; };
template <> struct TypeMap<float> { static const NPY_TYPES npyType = NPY_FLOAT; };
template <> struct TypeMap<double> { static const NPY_TYPES npyType = NPY_DOUBLE; };
void setupDims(PyArrayObject* im, ImageDimensions& dimsOut);
bool pyobjToVec(PyObject* list_array, Vec<double>& outVec);
// General array creation method
template <typename T>
PyArrayObject* createArray(int ndim, npy_intp* dims)
{
return ((PyArrayObject*)PyArray_SimpleNew(ndim, dims, TypeMap<T>::npyType));
}
template <typename T>
void setupImagePointers(PyArrayObject* imageIn, T** image, ImageDimensions& dims, PyArrayObject** argOut = nullptr, T** imageOut = nullptr)
{
setupInputPointers(imageIn, dims, image);
if ( argOut != nullptr && imageOut != nullptr )
setupOutputPointers(argOut, dims, imageOut);
}
template <typename T>
void setupInputPointers(PyArrayObject* imageIn, ImageDimensions& dims, T** image)
{
setupDims(imageIn, dims);
*image = (T*)PyArray_DATA(imageIn);
}
template <typename T>
void setupOutputPointers(PyArrayObject** imageOut, ImageDimensions& dims, T** image)
{
npy_intp pyDims[5];
for ( int i = 0; i < 3; ++i )
pyDims[i] = dims.dims.e[i];
pyDims[3] = dims.chan;
pyDims[4] = dims.frame;
*imageOut = createArray<T>(5, pyDims);
*image = (T*)PyArray_DATA(*imageOut);
std::memset(*image, 0, sizeof(T)*dims.getNumElements());
}
#include "PyWrapDef.h"
#include "../WrapCmds/CommandList.h"
#pragma once
#include "../Cuda/Vec.h"
#include "../Cuda/ImageDimensions.cuh"
#if defined(PY_BUILD)
#include "PyTypes.h"
#elif defined(MEX_BUILD)
#include "MexTypes.h"
#endif
#include <cstddef>
#include <cstring>
#include <algorithm>
namespace Script
{
inline ImageDimensions setupDims(const ArrayType* im)
{
ImageDimensions dimsOut;
dimsOut.dims = Vec<std::size_t>(1);
dimsOut.chan = 1;
dimsOut.frame = 1;
std::size_t numDims = ArrayInfo::getNDims(im);
const DimType* DIMS = ArrayInfo::getDims(im);
for ( int i=0; i < std::min<std::size_t>(numDims, 3); ++i )
dimsOut.dims.e[i] = (std::size_t) DIMS[i];
if ( numDims > 3 )
dimsOut.chan = (unsigned int)DIMS[3];
if ( numDims > 4 )
dimsOut.frame = (unsigned int)DIMS[4];
return std::move(dimsOut);
}
template <typename T>
void setupInputPointers(const ArrayType* imageIn, ImageDimensions& dims, T** image)
{
dims = setupDims(imageIn);
*image = ArrayInfo::getData<T>(imageIn);
}
template <typename T>
void setupOutputPointers(ArrayType** imageOut, ImageDimensions& dims, T** image)
{
DimType outDims[5];
for ( int i = 0; i < 3; ++i )
outDims[i] = dims.dims.e[i];
outDims[3] = dims.chan;
outDims[4] = dims.frame;
*imageOut = createArray<T>(5, outDims);
*image = ArrayInfo::getData<T>(*imageOut);
std::memset(*image, 0, sizeof(T)*dims.getNumElements());
}
template <typename T>
void setupImagePointers(const ArrayType* imageIn, T** image, ImageDimensions& dims, ArrayType** argOut = nullptr, T** imageOut = nullptr)
{
setupInputPointers(imageIn, dims, image);
if ( argOut != nullptr && imageOut != nullptr )
setupOutputPointers(argOut, dims, imageOut);
}
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment