Skip to content
Snippets Groups Projects
Commit 519f91df authored by Sebastian Wagner's avatar Sebastian Wagner
Browse files

Framework for compiling mex function with cmake.

build_oai --mexfiles
parent 1fb76157
Branches mexEnv
No related tags found
No related merge requests found
Showing
with 526 additions and 0 deletions
......@@ -258,6 +258,10 @@ function main() {
SIMUS_PHY=1
echo_info "Will compile dlsim, ulsim, ..."
shift;;
--mexfiles)
MEX_PHY=1
echo_info "Will compile mexfiles, ..."
shift;;
--core_simulators)
SIMUS_CORE=1
echo_info "Will compile security unitary tests"
......@@ -621,6 +625,20 @@ function main() {
done
fi
# Mexfiles
if [ "$MEX_PHY" = "1" ] ; then
cd $OPENAIR_DIR/cmake_targets/mexfiles
[ "$CLEAN" = "1" ] && rm -rf build
mkdir -p build
cd build
cmake ../
echo_info "Compiling stuff for mexfiles"
mexFileList="mexAdd mexGetTbs mexDlschEncoding"
for mexFile in $mexFileList ; do
make $mexFile
done
fi
# Core simulators
#############
if [ "$SIMUS_CORE" = "1" ] ; then
......
cmake_minimum_required(VERSION 2.8)
set(PACKAGE_NAME "mex")
set(PHYSIM True)
set(RF_BOARD None)
set(XFORMS True)
set(ENABLE_ITTI False)
set(DEBUG_PHY False)
set(MU_RECIEVER False)
set(RANDOM_BF False)
set(PBS_SIM False)
set(PERFECT_CE True)
set(NAS_UE False)
set(MESSAGE_CHART_GENERATOR False)
include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)
add_subdirectory(src)
cmake_minimum_required(VERSION 2.8)
#project(MEX)
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/src)
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/src/cmake) # add FindMatlab module
add_definitions(/DMATLAB_MEX_FILE) #define matlab macros
add_definitions(/DMX_COMPAT_32)
find_package(Matlab REQUIRED)
IF(MATLAB_FOUND)
message(STATUS "MATLAB Found, MATLAB MEX will be compiled.")
add_subdirectory(mex)
ELSE(MATLAB_FOUND)
MESSAGE("MATLAB not found...nothing will be built.")
ENDIF(MATLAB_FOUND)
EXPORTS mexFunction
\ No newline at end of file
# - this module looks for Matlab
# Defines:
# MATLAB_INCLUDE_DIR: include path for mex.h
# MATLAB_LIBRARIES: required libraries: libmex, libmx
# MATLAB_MEX_LIBRARY: path to libmex
# MATLAB_MX_LIBRARY: path to libmx
SET(MATLAB_FOUND 0)
IF( "$ENV{MATLAB_ROOT}" STREQUAL "" )
MESSAGE(STATUS "MATLAB_ROOT environment variable not set." )
MESSAGE(STATUS "In Linux this can be done in your user .bashrc file by appending the corresponding line, e.g:" )
MESSAGE(STATUS "export MATLAB_ROOT=/usr/local/MATLAB/R2012b" )
MESSAGE(STATUS "In Windows this can be done by adding system variable, e.g:" )
MESSAGE(STATUS "MATLAB_ROOT=D:\\Program Files\\MATLAB\\R2011a" )
ELSE("$ENV{MATLAB_ROOT}" STREQUAL "" )
FIND_PATH(MATLAB_INCLUDE_DIR mex.h
$ENV{MATLAB_ROOT}/extern/include)
INCLUDE_DIRECTORIES(${MATLAB_INCLUDE_DIR})
FIND_LIBRARY( MATLAB_MEX_LIBRARY
NAMES libmex mex
PATHS $ENV{MATLAB_ROOT}/bin $ENV{MATLAB_ROOT}/extern/lib
PATH_SUFFIXES glnxa64 glnx86 win64/microsoft win32/microsoft)
FIND_LIBRARY( MATLAB_MX_LIBRARY
NAMES libmx mx
PATHS $ENV{MATLAB_ROOT}/bin $ENV{MATLAB_ROOT}/extern/lib
PATH_SUFFIXES glnxa64 glnx86 win64/microsoft win32/microsoft)
MESSAGE (STATUS "MATLAB_ROOT: $ENV{MATLAB_ROOT}")
ENDIF("$ENV{MATLAB_ROOT}" STREQUAL "" )
# This is common to UNIX and Win32:
SET(MATLAB_LIBRARIES
${MATLAB_MEX_LIBRARY}
${MATLAB_MX_LIBRARY}
)
IF(MATLAB_INCLUDE_DIR AND MATLAB_LIBRARIES)
SET(MATLAB_FOUND 1)
MESSAGE(STATUS "Matlab libraries will be used")
ENDIF(MATLAB_INCLUDE_DIR AND MATLAB_LIBRARIES)
MARK_AS_ADVANCED(
MATLAB_LIBRARIES
MATLAB_MEX_LIBRARY
MATLAB_MX_LIBRARY
MATLAB_INCLUDE_DIR
MATLAB_FOUND
MATLAB_ROOT
)
add_subdirectory(mexAdd)
add_subdirectory(mexGetTbs)
add_subdirectory(mexDlschEncoding)
# compile mex
set(CPP_FILE mexAdd)
# set up matlab libraries
set(CPP_FILE_NAME ${CPP_FILE}.cpp)
include_directories(${MATLAB_INCLUDE_DIR})
#INCLUDE_DIRECTORIES(${MATLAB_INCLUDE_DIR} "/home/sebastian/Work/openairinterface5g/openair1/PHY/LTE_TRANSPORT/")
#GET_DIRECTORY_PROPERTY(output INCLUDE_DIRECTORIES)
#MESSAGE(WARNING ${output})
add_library(${CPP_FILE} SHARED ${CPP_FILE_NAME} ${CMAKE_SOURCE_DIR}/src/Matlabdef.def)
#include_directories("${OPENAIR_BIN_DIR}")
#include_directories("${OPENAIR1_DIR}")
#target_link_libraries(${CPP_FILE} ${MATLAB_LIBRARIES})
#target_include_directories(${CPP_FILE} PUBLIC "${OPENAIR1_DIR}")
# 32-bit or 64-bit mex
if(WIN32)
if (CMAKE_CL_64)
SET_TARGET_PROPERTIES(${CPP_FILE} PROPERTIES SUFFIX .mexw64)
else(CMAKE_CL_64)
SET_TARGET_PROPERTIES(${CPP_FILE} PROPERTIES SUFFIX .mexw32)
endif(CMAKE_CL_64)
else(WIN32)
if (CMAKE_SIZEOF_VOID_P MATCHES "8")
SET_TARGET_PROPERTIES(${CPP_FILE} PROPERTIES SUFFIX .mexa64 PREFIX "")
else(CMAKE_SIZEOF_VOID_P MATCHES "8")
SET_TARGET_PROPERTIES(${CPP_FILE} PROPERTIES SUFFIX .mexglx PREFIX "")
endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
endif(WIN32)
# install to /bin by default
#install(TARGETS ${CPP_FILE} DESTINATION ./bin)
/************************************************************************
Sample MEX code written by Fang Liu (leoliuf@gmail.com).
************************************************************************/
/* system header */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* MEX header */
#include <mex.h>
#include "matrix.h"
/* MEX entry function */
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
double *A, *B, *C;
mwSignedIndex Am, An, Bm, Bn;
/* argument check */
if ( nrhs != 2) {
mexErrMsgIdAndTxt("MATLAB:cudaAdd:inputmismatch",
"Input arguments must be 2!");
}
if ( nlhs != 1) {
mexErrMsgIdAndTxt("MATLAB:cudaAdd:outputmismatch",
"Output arguments must be 1!");
}
A = mxGetPr(prhs[0]);
B = mxGetPr(prhs[1]);
/* matrix size */
Am = (mwSignedIndex)mxGetM(prhs[0]);
An = (mwSignedIndex)mxGetN(prhs[0]);
Bm = (mwSignedIndex)mxGetM(prhs[1]);
Bn = (mwSignedIndex)mxGetN(prhs[1]);
if ( Am != Bm || An != Bn) {
mexErrMsgIdAndTxt("MATLAB:cudaAdd:sizemismatch",
"Input matrices must have the same size!");
}
/* allocate output */
plhs[0] = mxCreateDoubleMatrix(Am, An, mxREAL);
C = mxGetPr(plhs[0]);
/* do loop calculation */
for (int i=0; i<Am; i++){
for (int j=0; j<An; j++){
C[i*An+j]=A[i*An+j]+B[i*An+j];
}
}
}
# compile mex
set(CPP_FILE mexDlschEncoding)
# set up matlab libraries
set(CPP_FILE_NAME ${CPP_FILE}.cpp)
INCLUDE_DIRECTORIES(${MATLAB_INCLUDE_DIR})
add_library(${CPP_FILE} SHARED ${CPP_FILE_NAME} ${CMAKE_SOURCE_DIR}/src/Matlabdef.def)
target_link_libraries(${CPP_FILE} PHY ${MATLAB_LIBRARIES})
# 32-bit or 64-bit mex
if(WIN32)
if (CMAKE_CL_64)
SET_TARGET_PROPERTIES(${CPP_FILE} PROPERTIES SUFFIX .mexw64)
else(CMAKE_CL_64)
SET_TARGET_PROPERTIES(${CPP_FILE} PROPERTIES SUFFIX .mexw32)
endif(CMAKE_CL_64)
else(WIN32)
if (CMAKE_SIZEOF_VOID_P MATCHES "8")
SET_TARGET_PROPERTIES(${CPP_FILE} PROPERTIES SUFFIX .mexa64 PREFIX "")
else(CMAKE_SIZEOF_VOID_P MATCHES "8")
SET_TARGET_PROPERTIES(${CPP_FILE} PROPERTIES SUFFIX .mexglx PREFIX "")
endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
endif(WIN32)
# install to /bin by default
#install(TARGETS ${CPP_FILE} DESTINATION ../bin)
//#include "../../../defs.h"
#include <mex.h>
#include "PHY/types.h"
#include "PHY/defs.h"
#include "PHY/vars.h"
/*==============================================================================
* dlsch_encoding.c
*
* Returns the encoded bit sequence.
*
* example: e = dlsch_encoding(bits,struct1,struct2)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
// #define DEBUG_DLSCH_ENCODING
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
unsigned char *input_buffer;
unsigned char *e; // encoded bits = output
unsigned char mcs=0;
unsigned char mod_order=2;
unsigned char num_pdcch_symbols=1;
unsigned char harq_pid=0;
unsigned char subframe=0;
unsigned char Kmimo=1;
unsigned char Mdlharq=8;
unsigned char abstraction_flag;
int ret, input_buffer_length;
unsigned int G;
mxArray *tmp;
LTE_eNB_DLSCH_t* dlsch;
LTE_DL_FRAME_PARMS *frame_parms;
time_stats_t dlsch_rate_matching_stats, dlsch_turbo_encoding_stats, dlsch_interleaving_stats;
/* Check proper input and output. */
if(nrhs!=3)
mexErrMsgTxt("Three inputs required.");
else if(nlhs > 1)
mexErrMsgTxt("Too many output arguments.");
else if(!mxIsStruct(prhs[1]))
mexErrMsgTxt("Second input must be a structure.");
else if(!mxIsStruct(prhs[2]))
mexErrMsgTxt("Third input must be a structure.");
// Init CRC tables
crcTableInit();
/* Create new dlsch */
tmp = mxGetField(prhs[2],0,"Kmimo");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Kmimo' in input argument 3.");
} else {
Kmimo = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"Mdlharq");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Mdlharq' in input argument 3.");
} else {
Mdlharq = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"abstraction_flag");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'abstraction_flag' in input argument 2.");
} else {
abstraction_flag = (unsigned char) mxGetScalar(tmp);
}
dlsch = new_eNB_dlsch(Kmimo,Mdlharq,25,abstraction_flag);
/* Allocate input */
input_buffer = (unsigned char*) mxGetData(prhs[0]);
(mxGetM(prhs[0]) > 1) ? (input_buffer_length = mxGetM(prhs[0])) : (input_buffer_length = mxGetN(prhs[0]));
tmp = mxGetField(prhs[2],0,"mcs");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'mcs' in input argument 3.");
} else {
mcs = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"harq_pid");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'harq_pid' in input argument 3.");
} else {
harq_pid = (unsigned char) mxGetScalar(tmp);
}
dlsch->current_harq_pid = harq_pid;
dlsch->harq_processes[harq_pid]->mcs = mcs;
tmp = mxGetField(prhs[2],0,"rvidx");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'rvidx' in input argument 3.");
} else {
dlsch->harq_processes[harq_pid]->rvidx = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"Nl");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Nl' in input argument 3.");
} else {
dlsch->harq_processes[harq_pid]->Nl = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[2],0,"Ndi");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'Ndi' in input argument 3.");
} else {
dlsch->harq_processes[harq_pid]->Ndi = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"rb_alloc");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'rb_alloc' in input argument 2.");
} else {
dlsch->rb_alloc[0] = (unsigned int) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"nb_rb");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'nb_rb' in input argument 2.");
} else {
dlsch->nb_rb = (unsigned short) mxGetScalar(tmp);
}
dlsch->harq_processes[harq_pid]->TBS = dlsch_tbs25[get_I_TBS(mcs)][dlsch->nb_rb-1];
// Check if input buffer length is correct
if ((input_buffer_length) != (dlsch->harq_processes[harq_pid]->TBS/8+4)) {
free_eNB_dlsch(dlsch);
mexErrMsgTxt("Length of the input buffer is incorrect.");
}
tmp = mxGetField(prhs[1],0,"num_pdcch_symbols");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'num_pdcch_symbols' in input argument 2.");
} else {
num_pdcch_symbols = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"subframe");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'subframe' in input argument 2.");
} else {
subframe = (unsigned char) mxGetScalar(tmp);
}
// Create a LTE_DL_FRAME_PARMS structure and assign required params
frame_parms = calloc(1,sizeof(LTE_DL_FRAME_PARMS));
frame_parms->N_RB_DL = (unsigned char) dlsch->nb_rb;
tmp = mxGetField(prhs[1],0,"frame_type");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'frame_type' in input argument 2.");
} else {
frame_parms->frame_type = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"mode1_flag");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'frame_type' in input argument 2.");
} else {
frame_parms->mode1_flag = (unsigned char) mxGetScalar(tmp);
}
tmp = mxGetField(prhs[1],0,"Ncp");
if (tmp == NULL) {
mexErrMsgTxt("Non-existing field 'frame_type' in input argument 2.");
} else {
frame_parms->Ncp = (unsigned char) mxGetScalar(tmp);
}
mod_order = get_Qm(dlsch->harq_processes[harq_pid]->mcs);
G = get_G(frame_parms,dlsch->nb_rb,dlsch->rb_alloc,mod_order,dlsch->harq_processes[harq_pid]->Nl,num_pdcch_symbols,0,subframe);
#ifdef DEBUG_DLSCH_ENCODING
mexPrintf("dlsch->current_harq_pid = %d\n", dlsch->current_harq_pid);
mexPrintf("dlsch->harq_processes[harq_pid]->rvidx = %d\n", dlsch->harq_processes[harq_pid]->rvidx);
mexPrintf("dlsch->harq_processes[harq_pid]->Nl = %d\n", dlsch->harq_processes[harq_pid]->Nl);
mexPrintf("dlsch->harq_processes[harq_pid]->Ndi = %d\n", dlsch->harq_processes[harq_pid]->Ndi);
mexPrintf("mod_order = %d\n",mod_order);
mexPrintf("G = %d\n",G);
mexPrintf("frame_parms->N_RB_DL = %d\n", frame_parms->N_RB_DL);
mexPrintf("frame_parms->frame_type = %d\n", frame_parms->frame_type);
mexPrintf("frame_parms->mode1_flag = %d\n", frame_parms->mode1_flag);
mexPrintf("frame_parms->Ncp = %d\n", frame_parms->Ncp);
#endif
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(G, 1, mxUINT8_CLASS, mxREAL);
e = (unsigned char*) mxGetPr(plhs[0]);
/* Algo */
ret = dlsch_encoding(input_buffer, frame_parms, num_pdcch_symbols, dlsch, 0, subframe,&dlsch_rate_matching_stats, &dlsch_turbo_encoding_stats, &dlsch_interleaving_stats);
/* Assign output */
memcpy((void*) e, (void*) dlsch->e,G);
/* free */
free_eNB_dlsch(dlsch);
free(frame_parms);
}
# compile mex
set(CPP_FILE mexGetTbs)
# set up matlab libraries
set(CPP_FILE_NAME ${CPP_FILE}.cpp)
INCLUDE_DIRECTORIES(${MATLAB_INCLUDE_DIR})
add_library(${CPP_FILE} SHARED ${CPP_FILE_NAME} ${CMAKE_SOURCE_DIR}/src/Matlabdef.def)
target_link_libraries(${CPP_FILE} PHY ${MATLAB_LIBRARIES})
# 32-bit or 64-bit mex
if(WIN32)
if (CMAKE_CL_64)
SET_TARGET_PROPERTIES(${CPP_FILE} PROPERTIES SUFFIX .mexw64)
else(CMAKE_CL_64)
SET_TARGET_PROPERTIES(${CPP_FILE} PROPERTIES SUFFIX .mexw32)
endif(CMAKE_CL_64)
else(WIN32)
if (CMAKE_SIZEOF_VOID_P MATCHES "8")
SET_TARGET_PROPERTIES(${CPP_FILE} PROPERTIES SUFFIX .mexa64 PREFIX "")
else(CMAKE_SIZEOF_VOID_P MATCHES "8")
SET_TARGET_PROPERTIES(${CPP_FILE} PROPERTIES SUFFIX .mexglx PREFIX "")
endif (CMAKE_SIZEOF_VOID_P MATCHES "8")
endif(WIN32)
# install to /bin by default
#install(TARGETS ${CPP_FILE} DESTINATION ../bin)
#include <mex.h>
//#include "defs.h"
#include "PHY/LTE_TRANSPORT/dlsch_tbs.h"
//#include "PHY/LTE_TRANSPORT/proto.h"
/*==============================================================================
* get_tbs.c
*
* Returns the transport block size (TBS) given the MCS and the number of RBs.
*
* example: tbs = get_tbs(16,25)
*
* Author: Sebastian Wagner
* Date: 23-07-2012
*
===============================================================================*/
//unsigned char get_I_TBS(unsigned char I_MCS);
unsigned char get_I_TBS(unsigned char I_MCS)
{
if (I_MCS < 10)
return(I_MCS);
else if (I_MCS == 10)
return(9);
else if (I_MCS < 17)
return(I_MCS-1);
else if (I_MCS == 17)
return(15);
else return(I_MCS-2);
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]
)
{
/* Declare */
unsigned char mcs, nb_rb;
unsigned int *tbs;
/* Check correct I/O number */
if(nrhs!=2) {
mexErrMsgTxt("Two inputs required.");
} else if(nlhs>1) {
mexErrMsgTxt("Too many output arguments.");
}
/* Allocate input */
mcs = (unsigned char) mxGetScalar(prhs[0]);
nb_rb = (unsigned char) mxGetScalar(prhs[1]);
/* Check input */
if((mcs < 0) || (mcs > 28)) {
mexErrMsgTxt("Wrong MCS index.");
} else if((nb_rb<=0) || (nb_rb>25)) {
mexErrMsgTxt("Unsupported number of RBs.");
};
/* Allocate Output */
plhs[0] = mxCreateNumericMatrix(1, 1, mxUINT32_CLASS, mxREAL);
tbs = (unsigned int*) mxGetPr(plhs[0]);
/* Algo */
*tbs = dlsch_tbs25[get_I_TBS(mcs)][nb_rb-1];
}
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