Monte Carlo eXtreme (MCX)
Macros | Functions | Variables
pmcx.cpp File Reference

Python interface using Pybind11 for MCX. More...

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <iostream>
#include <string>
#include "mcx_utils.h"
#include "mcx_core.h"
#include "mcx_const.h"
#include "mcx_shapes.h"
#include <pybind11/iostream.h>
Include dependency graph for pmcx.cpp:

Macros

#define PYBIND11_DETAILED_ERROR_MESSAGES
 
#define RAND_WORD_LEN   4
 
#define GET_SCALAR_FIELD(src_pydict, dst_mcx_config, property, py_type)
 
#define GET_VEC3_FIELD(src, dst, prop, type)
 
#define GET_VEC4_FIELD(src, dst, prop, type)
 
#define GET_VEC34_FIELD(src, dst, prop, type)
 

Functions

 pybind11::PYBIND11_RUNTIME_EXCEPTION (runtime_error, PyExc_RuntimeError)
 
void parseVolume (const py::dict &user_cfg, Config &mcx_config)
 
void parse_config (const py::dict &user_cfg, Config &mcx_config)
 
void cleanup_configs (MCXGPUInfo *&gpu_info, MCXConfig &mcx_config)
 
py::dict pmcx_interface (const py::dict &user_cfg)
 
int mcx_throw_exception (const int id, const char *msg, const char *filename, const int linenum)
 Error reporting function in PMCX, equivalent to mcx_error in binary mode. More...
 
void print_mcx_usage ()
 
void mcx_python_flush ()
 Force matlab refresh the command window to print all buffered messages.
 
py::dict pmcx_interface_wargs (py::args args, const py::kwargs &kwargs)
 
py::str print_version ()
 
py::list get_GPU_info ()
 
 PYBIND11_MODULE (_pmcx, m)
 

Variables

float * det_ps = nullptr
 
int dim_det_ps [2] = {0, 0}
 buffer to receive data from cfg.detphotons field
 
int seed_byte = 0
 dimensions of the cfg.detphotons array
 

Detailed Description

Python interface using Pybind11 for MCX.

Macro Definition Documentation

◆ GET_SCALAR_FIELD

#define GET_SCALAR_FIELD (   src_pydict,
  dst_mcx_config,
  property,
  py_type 
)
Value:
if ((src_pydict).contains(#property))\
{try {(dst_mcx_config).property = py_type((src_pydict)[#property]);\
std::cout << #property << ": " << (float) (dst_mcx_config).property << std::endl;} \
catch (const std::runtime_error &err)\
{throw py::type_error(std::string("Failed to assign MCX property " + std::string(#property) + ". Reason: " + err.what()));}\
}

Macro to find and extract a scalar property from a source Python dictionary configuration and assign it in a destination MCX Config. The scalar is cast to the python type before assignment.

◆ GET_VEC34_FIELD

#define GET_VEC34_FIELD (   src,
  dst,
  prop,
  type 
)
Value:
if (src.contains(#prop)) {try {auto list = py::list(src[#prop]);\
dst.prop = {list[0].cast<type>(), list[1].cast<type>(), list[2].cast<type>(), list.size() == 4 ? list[3].cast<type>() : dst.prop.w}; \
std::cout << #prop << ": [" << dst.prop.x << ", " << dst.prop.y << ", " << dst.prop.z << ", " << dst.prop.w << "]\n";} \
catch (const std::runtime_error &err ) {throw py::type_error(std::string("Failed to assign MCX property " + std::string(#prop) + ". Reason: " + err.what()));} \
}

◆ GET_VEC3_FIELD

#define GET_VEC3_FIELD (   src,
  dst,
  prop,
  type 
)
Value:
if (src.contains(#prop)) {try {auto list = py::list(src[#prop]);\
dst.prop = {list[0].cast<type>(), list[1].cast<type>(), list[2].cast<type>()};\
std::cout << #prop << ": [" << dst.prop.x << ", " << dst.prop.y << ", " << dst.prop.z << "]\n";} \
catch (const std::runtime_error &err ) {throw py::type_error(std::string("Failed to assign MCX property " + std::string(#prop) + ". Reason: " + err.what()));}}

◆ GET_VEC4_FIELD

#define GET_VEC4_FIELD (   src,
  dst,
  prop,
  type 
)
Value:
if (src.contains(#prop)) {try {auto list = py::list(src[#prop]);\
dst.prop = {list[0].cast<type>(), list[1].cast<type>(), list[2].cast<type>(), list[3].cast<type>()}; \
std::cout << #prop << ": [" << dst.prop.x << ", " << dst.prop.y << ", " << dst.prop.z << ", " << dst.prop.w << "]\n";} \
catch (const std::runtime_error &err ) {throw py::type_error(std::string("Failed to assign MCX property " + std::string(#prop) + ". Reason: " + err.what()));}}

◆ RAND_WORD_LEN

#define RAND_WORD_LEN   4

number of Words per RNG state

Function Documentation

◆ cleanup_configs()

void cleanup_configs ( MCXGPUInfo *&  gpu_info,
MCXConfig mcx_config 
)
inline

Function that's called to cleanup any memory/configs allocated by PMCX. It is used in both normal and exceptional termination of the application

Parameters
gpu_inforeference to an array of MCXGPUInfo data structure
mcx_configreference to MCXConfig data structure
Here is the call graph for this function:

◆ get_GPU_info()

py::list get_GPU_info ( )

mcxconfig: structure to store all simulation parameters

gpuinfo: structure to store GPU information

Here is the call graph for this function:

◆ mcx_throw_exception()

int mcx_throw_exception ( const int  id,
const char *  msg,
const char *  filename,
const int  linenum 
)

Error reporting function in PMCX, equivalent to mcx_error in binary mode.

Parameters
[in]ida single integer for the types of the error
[in]msgthe error message string
[in]filenamethe unit file name where this error is raised
[in]linenumthe line number in the file where this error is raised

◆ parseVolume()

void parseVolume ( const py::dict &  user_cfg,
Config mcx_config 
)

Determines the type of volume passed to the interface and decides how to copy it to MCXConfig.

Parameters
user_cfg
mcx_config

float to half conversion https://stackoverflow.com/questions/3026441/float32-to-float16/5587983#5587983 https://gamedev.stackexchange.com/a/17410 (for denorms)

◆ pmcx_interface()

py::dict pmcx_interface ( const py::dict &  user_cfg)

gpuInfo: structure to store GPU information

activeDev: count of total active GPUs to be used

The next step, we identify gpu number and query all GPU info

Validate all input fields, and warn incompatible inputs

One must define the domain and properties

Initialize all buffers necessary to store the output variables

Start multiple threads, one thread to run portion of the simulation on one CUDA GPU, all in parallel

Enclose all simulation calls inside a try/catch construct for exception handling

Call the main simulation host function to start the simulation

If error is detected, gracefully terminate the mex and return back to Python

return the final optical properties for polarized MCX simulation

Clear up simulation data structures by calling the destructors

◆ print_version()

py::str print_version ( )

mcxconfig: structure to store all simulation parameters

Here is the call graph for this function: