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

Run matlab post-build script to move mex file to appropriate src directory and...

Run matlab post-build script to move mex file to appropriate src directory and rebuild script wrappers
parent 2a0e15d6
No related branches found
No related tags found
No related merge requests found
...@@ -31,7 +31,7 @@ Thumbs.db ...@@ -31,7 +31,7 @@ Thumbs.db
# Ignore CMake cache and build directiories (assume build*/) # Ignore CMake cache and build directiories (assume build*/)
CmakeCache.txt CmakeCache.txt
build*/ /build*/
**/CMakeFiles **/CMakeFiles
# Ignore pycache folder # Ignore pycache folder
......
...@@ -10,7 +10,7 @@ set(HYDRA_MODULE_NAME "HIP") ...@@ -10,7 +10,7 @@ set(HYDRA_MODULE_NAME "HIP")
find_package(CUDA REQUIRED) find_package(CUDA REQUIRED)
find_package(OpenMP REQUIRED) find_package(OpenMP REQUIRED)
find_package(Matlab) find_package(Matlab COMPONENTS MAIN_PROGRAM)
find_package(Python COMPONENTS Development NumPy) find_package(Python COMPONENTS Development NumPy)
# Setup backend Hydra CUDA library (static) for cuda building # Setup backend Hydra CUDA library (static) for cuda building
......
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Set List of Files to Exclude %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear mex
excludeList = ...
{'Cuda.m';
'DeviceCount.m';
'DeviceStats.m'};
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% remember curent path
curPath = pwd();
% find where the image processing package is
cudaPath = fileparts(which('HIP.BuildMexObject'));
cd(cudaPath)
% create the m files that correspond to the commands in the mex interface
HIP.BuildMexObject(fullfile('..','..','c',['Mex.' mexext]),'Cuda','HIP');
packagePath = cudaPath;
cudaPath = fullfile(cudaPath,'@Cuda');
% get a list of all of the functions in the class
dList = dir(fullfile(cudaPath,'*.m'));
% wrap each function
numFunctions = 0;
for i=1:length(dList)
if (any(strcmpi(excludeList,dList(i).name)))
continue;
end
% copy the file from the class to the package
newFile = fullfile(packagePath,dList(i).name);
% if (exist(newFile,'file') && ~strcmpi(dList(i).name,'Help.m') && ~strcmpi(dList(i).name,'Info.m'))
% % fprintf(1,'File exist: %s\n',newFile);
% continue;
% end
% fprintf(1,'Making undetected file: %s\n',newFile);
% get all of the lines
f = fopen(fullfile(cudaPath,dList(i).name),'rt');
curLine = fgetl(f);
textLines = {};
while ischar(curLine)
textLines = [textLines;{curLine}];
curLine = fgetl(f);
end
fclose(f);
% write out the new data
f = fopen(newFile,'wt');
funcCallFilled = '';
for j=1:length(textLines)
curLine = textLines{j};
% check for comment line
if (strcmpi(curLine(1),'%'))
%check if it is the protype line
protoLineExpr = '\.Cuda\.';
protoIdx = regexpi(curLine,protoLineExpr);
if (~isempty(protoIdx))
% remove the class part of the path
fprintf(f, '%s\n',curLine([1:protoIdx,protoIdx+6:end]));
continue;
end
% doesn't me other searches write as is
fprintf(f,'%s\n',curLine);
continue;
end
% figure out if this is the function line
funcLineExpr = 'function (?<out>.*) = (?<name>\w+)\((?<param>.*)\)';
funcCall = regexpi(curLine,funcLineExpr,'names');
if (~isempty(funcCall))
funcCallFilled = funcCall;
fprintf(f,'\nfunction %s = %s(%s)\n',funcCall.out,funcCall.name,funcCall.param);
fprintf(f,' try\n');
fprintf(f,' %s = HIP.Cuda.%s(%s);\n',funcCall.out,funcCall.name,funcCall.param);
fprintf(f,' catch errMsg\n');
localFuctionCall = sprintf('%s = HIP.Local.%s(%s)',funcCall.out,funcCall.name,funcCall.param);
fprintf(f,' warning(errMsg.message);\n');
fprintf(f,' %s;\n', localFuctionCall);
fprintf(f,' end\n');
continue;
end
mexCallExpr = '\.Mex';
mexPos = regexpi(curLine,mexCallExpr);
if (~isempty(mexPos))
% this was written above in the Cuda version of the function
continue
end
% does not meet any criteria, write as is
fprintf(f, '%s\n',curLine);
end
fclose(f);
numFunctions = numFunctions +1;
%place the local function call stub here
if (isempty(funcCallFilled))
continue
end
if (~exist(fullfile(packagePath,'+Local'),'dir'))
mkdir(fullfile(packagePath,'+Local'));
end
localFuncFileName = fullfile(packagePath,'+Local',[funcCallFilled.name,'.m']);
if (~exist(localFuncFileName,'file'))
f = fopen(localFuncFileName,'wt');
fprintf(f, 'function %s = %s(%s,suppressWarning)\n',funcCallFilled.out,funcCallFilled.name,funcCallFilled.param);
fprintf(f, ' error(''%s not yet implemented in MATLAB!''); %%delete this line when implemented\n',funcCallFilled.name);
fprintf(f, ' if (~exist(''suppressWarning'',''var'') || isempty(suppressWarning) || ~suppressWarning)\n');
fprintf(f, ' warning(''Falling back to matlab.'');\n');
fprintf(f, ' end\n');
fprintf(f, ' \n');
fprintf(f, ' if (~exist(''numIterations'',''var'') || isempty(numIterations))\n');
fprintf(f, ' numIterations = 1;\n');
fprintf(f, ' end\n');
fprintf(f, ' \n');
fprintf(f, ' arrayOut = arrayIn;\n');
fprintf(f, ' for t=1:size(arrayIn,5)\n');
fprintf(f, ' for c=1:size(arrayIn,4)\n');
fprintf(f, ' for i=1:numIterations\n');
fprintf(f, ' %% implement this function here\n');
fprintf(f, ' arrayOut(:,:,:,c,t) = arrayIn(:,:,:,c,t);\n');
fprintf(f, ' end\n');
fprintf(f, ' end\n');
fprintf(f, ' end\n');
fprintf(f, 'end\n');
fclose(f);
end
end
fprintf('HIP BuildScript wrote %d functions\n',numFunctions);
% go back to the original directory
cd(curPath)
function BuildMexObject(mexFile, objectName, parentPackage) function BuildMexClass(mexFile, packagePath, className, parentPackage)
oldPath = pwd(); oldPath = pwd();
cleanupObj = onCleanup(@()(cleanupFunc(oldPath))); cleanupObj = onCleanup(@()(cleanupFunc(oldPath)));
...@@ -8,47 +8,46 @@ function BuildMexObject(mexFile, objectName, parentPackage) ...@@ -8,47 +8,46 @@ function BuildMexObject(mexFile, objectName, parentPackage)
mexFunc = str2func(mexName); mexFunc = str2func(mexName);
commandList = mexFunc('Info'); commandList = mexFunc('Info');
cd(oldPath); cd(packagePath);
% Delete old function definitions % Delete old function definitions
if ( exist(['@' objectName], 'dir') ) if ( exist(['@' className], 'dir') )
delete(fullfile(['@' objectName], '*.m')); delete(fullfile(['@' className], '*.m'));
end end
makeClassdef(objectName, mexName, commandList); makeClassdef(className, mexName, commandList);
for i=1:length(commandList) for i=1:length(commandList)
makeStaticMethod(objectName, mexName, commandList(i), parentPackage); makeStaticMethod(className, mexName, commandList(i), parentPackage);
end end
copyfile(mexFile, ['@' objectName]); copyfile(mexFile, ['@' className]);
clear mex
end end
function makeClassdef(objectName, mexName, commandList) function makeClassdef(className, mexName, commandList)
if ( ~exist(['@' objectName],'dir') ) if ( ~exist(['@' className],'dir') )
mkdir(['@' objectName]); mkdir(['@' className]);
end end
objFile = fopen(fullfile(['@' objectName],[objectName '.m']), 'wt'); classFile = fopen(fullfile(['@' className],[className '.m']), 'wt');
fprintf(objFile, 'classdef (Abstract,Sealed) %s\n', objectName); fprintf(classFile, 'classdef (Abstract,Sealed) %s\n', className);
fprintf(objFile, 'methods (Static)\n'); fprintf(classFile, 'methods (Static)\n');
for i=1:length(commandList) for i=1:length(commandList)
fprintf(objFile, ' %s\n', makePrototypeString(commandList(i))); fprintf(classFile, ' %s\n', makePrototypeString(commandList(i)));
end end
fprintf(objFile, 'end\n'); fprintf(classFile, 'end\n');
fprintf(objFile, 'methods (Static, Access = private)\n'); fprintf(classFile, 'methods (Static, Access = private)\n');
fprintf(objFile, ' varargout = %s(command, varargin)\n', mexName); fprintf(classFile, ' varargout = %s(command, varargin)\n', mexName);
fprintf(objFile, 'end\n'); fprintf(classFile, 'end\n');
fprintf(objFile, 'end\n'); fprintf(classFile, 'end\n');
fclose(objFile); fclose(classFile);
end end
function makeStaticMethod(objectName, mexName, commandInfo, parentPackage) function makeStaticMethod(className, mexName, commandInfo, parentPackage)
methodFile = fopen(fullfile(['@' objectName],[commandInfo.command '.m']), 'wt'); methodFile = fopen(fullfile(['@' className],[commandInfo.command '.m']), 'wt');
helpLines = strsplit(commandInfo.help, '\n', 'CollapseDelimiters',false); helpLines = strsplit(commandInfo.help, '\n', 'CollapseDelimiters',false);
validIdx = find(cellfun(@(x)(~isempty(x)), helpLines)); validIdx = find(cellfun(@(x)(~isempty(x)), helpLines));
...@@ -71,7 +70,7 @@ function makeStaticMethod(objectName, mexName, commandInfo, parentPackage) ...@@ -71,7 +70,7 @@ function makeStaticMethod(objectName, mexName, commandInfo, parentPackage)
fprintf(methodFile, '%% %s - %s\n', commandInfo.command, summaryString); fprintf(methodFile, '%% %s - %s\n', commandInfo.command, summaryString);
% Write call protoype string % Write call protoype string
fprintf(methodFile, '%% %s\n', makePrototypeString(commandInfo,objectName,parentPackage,true)); fprintf(methodFile, '%% %s\n', makePrototypeString(commandInfo,className,parentPackage,true));
% Write remaining help lines directly % Write remaining help lines directly
if ( length(validIdx) > 2 ) if ( length(validIdx) > 2 )
...@@ -82,13 +81,13 @@ function makeStaticMethod(objectName, mexName, commandInfo, parentPackage) ...@@ -82,13 +81,13 @@ function makeStaticMethod(objectName, mexName, commandInfo, parentPackage)
% Output function body % Output function body
fprintf(methodFile, 'function %s\n', makePrototypeString(commandInfo)); fprintf(methodFile, 'function %s\n', makePrototypeString(commandInfo));
fprintf(methodFile, ' %s;\n', makeCommandString(objectName, mexName,commandInfo,parentPackage)); fprintf(methodFile, ' %s;\n', makeCommandString(className, mexName,commandInfo,parentPackage));
fprintf(methodFile, 'end\n'); fprintf(methodFile, 'end\n');
fclose(methodFile); fclose(methodFile);
end end
function commandString = makeCommandString(objectName, mexName, commandInfo, parentPackage) function commandString = makeCommandString(className, mexName, commandInfo, parentPackage)
commandString = ''; commandString = '';
if ( ~isempty(commandInfo.outArgs) ) if ( ~isempty(commandInfo.outArgs) )
commandString = ['[' makeCommaList(commandInfo.outArgs) '] = ']; commandString = ['[' makeCommaList(commandInfo.outArgs) '] = '];
...@@ -100,7 +99,7 @@ function commandString = makeCommandString(objectName, mexName, commandInfo, par ...@@ -100,7 +99,7 @@ function commandString = makeCommandString(objectName, mexName, commandInfo, par
parentPackage = [parentPackage '.']; parentPackage = [parentPackage '.'];
end end
mexCall = [parentPackage objectName '.' mexName]; mexCall = [parentPackage className '.' mexName];
commandString = [commandString mexCall '(''' commandInfo.command '''']; commandString = [commandString mexCall '(''' commandInfo.command ''''];
if ( ~isempty(commandInfo.inArgs) ) if ( ~isempty(commandInfo.inArgs) )
commandString = [commandString ',' makeCommaList(commandInfo.inArgs)]; commandString = [commandString ',' makeCommaList(commandInfo.inArgs)];
...@@ -108,9 +107,9 @@ function commandString = makeCommandString(objectName, mexName, commandInfo, par ...@@ -108,9 +107,9 @@ function commandString = makeCommandString(objectName, mexName, commandInfo, par
commandString = [commandString ')']; commandString = [commandString ')'];
end end
function protoString = makePrototypeString(commandInfo, objectName, parentPackage, leaveOptBrackets) function protoString = makePrototypeString(commandInfo, className, parentPackage, leaveOptBrackets)
if ( ~exist('objectName','var') ) if ( ~exist('className','var') )
objectName = []; className = [];
end end
if ( ~exist('parentPackage','var') ) if ( ~exist('parentPackage','var') )
parentPackage = []; parentPackage = [];
...@@ -131,8 +130,8 @@ function protoString = makePrototypeString(commandInfo, objectName, parentPackag ...@@ -131,8 +130,8 @@ function protoString = makePrototypeString(commandInfo, objectName, parentPackag
protoString = [protoString ' = ']; protoString = [protoString ' = '];
end end
if ( ~isempty(objectName) ) if ( ~isempty(className) )
protoString = [protoString parentPackage objectName '.']; protoString = [protoString parentPackage className '.'];
end end
protoString = [protoString commandInfo.command '(']; protoString = [protoString commandInfo.command '('];
...@@ -156,5 +155,4 @@ end ...@@ -156,5 +155,4 @@ end
function cleanupFunc(oldPath) function cleanupFunc(oldPath)
cd(oldPath); cd(oldPath);
clear mex;
end end
function autoInstallMex(moduleName, mexFile)
className = 'Cuda';
hipDir = fullfile(pwd(),'..',['+' moduleName]);
if ( ~exist(hipDir,'dir') )
mkdir(hipDir);
end
BuildMexClass(mexFile, hipDir, className, moduleName);
wrapClassFuncs(hipDir, className);
end
function wrapClassFuncs(packageDir, className)
classDir = fullfile(packageDir, ['@' className]);
% Exclude internal/cuda-specific functions
excludeList = {[className '.m'];
'DeviceCount.m';
'DeviceStats.m'};
% get a list of all of the functions in the class
funcList = dir(fullfile(classDir,'*.m'));
for i=1:length(funcList)
if (any(strcmpi(excludeList, funcList(i).name)))
continue;
end
wrapFile = fullfile(packageDir,funcList(i).name);
inFile = fullfile(classDir,funcList(i).name);
inData = fileread(inFile);
inLines = strsplit(inData, {'\n','\r\n'});
wrapLines = updateLines(inLines, className);
wrapStr = strjoin(wrapLines, '\n');
fid = fopen(wrapFile, 'wt');
fprintf(fid,'%s', wrapStr);
fclose(fid);
end
end
function outLines = updateLines(inLines, className)
outLines = {};
for i=1:length(inLines)
chkLine = inLines{i};
classExpr = regexptranslate('escape', ['.' className '.']);
commentProtoExpr = ['(%.*?)' classExpr];
funcLineExpr = 'function (?<out>.*) = (?<name>\w+)\((?<params>.*)\)';
commentProto = regexpi(chkLine, commentProtoExpr, 'once');
funcLine = regexpi(chkLine, funcLineExpr, 'once');
if ( ~isempty(commentProto) )
outLines = [outLines; {regexprep(chkLine, commentProtoExpr, '$1.')}];
elseif ( ~isempty(funcLine) )
funcCall = regexpi(chkLine, funcLineExpr, 'names');
outLines = [outLines; {sprintf('function %s = %s(%s)', funcCall.out, funcCall.name, funcCall.params)}];
outLines = [outLines; {sprintf(' try')}];
outLines = [outLines; {sprintf(' %s = HIP.Cuda.%s(%s);',funcCall.out,funcCall.name,funcCall.params)}];
outLines = [outLines; {sprintf(' catch errMsg')}];
outLines = [outLines; {sprintf(' warning(errMsg.message);')}];
outLines = [outLines; {sprintf(' %s = HIP.Local.%s(%s);',funcCall.out,funcCall.name,funcCall.params)}];
outLines = [outLines; {sprintf(' end')}];
outLines = [outLines; {sprintf('end')}];
outLines = [outLines; {''}];
break;
else
outLines = [outLines; {chkLine}];
end
end
end
add_custom_command(TARGET HydraMex
POST_BUILD
COMMAND ${Matlab_MAIN_PROGRAM} -nosplash -nodisplay -nodesktop $<$<PLATFORM_ID:Windows>:-wait> -r "autoInstallMex('${HYDRA_MODULE_NAME}', '$<TARGET_FILE:HydraMex>');exit;"
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/src/MATLAB/build-scripts
VERBATIM USES_TERMINAL
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment