Code covered by the BSD License  

Highlights from
Expectation Maximization of Gaussian Mixture Models via CUDA

image thumbnail
from Expectation Maximization of Gaussian Mixture Models via CUDA by Andrew Harp
CUDA enabled parallel EM for Gaussian Mixture Models, providing over 100x performance increases.

nvmex_helper(varargin)
function errorCode = nvmex_helper(varargin)
%MEX_HELPER is a helper function that contains the code that MEX.M (an 
%   autogenerated file) executes.  It sets up the inputs to call mex.pl (on PC)
%   and mex (on Unix).
%  
%   For information on how to use MEX see MEX help by typing "help mex" or 
%   "mex -h".

%   Copyright 1984-2006 The MathWorks, Inc.
%   $Revision: 1.1.6.1 $

if isunix

    mexname = get_mex_opts(varargin{:});
    
    if ~isempty(mexname)
        [loaded_m, loaded_mex] = inmem;
        if ~isempty(loaded_mex)
            clear_mex_file(mexname);
        end
    end
    
    args = [' "ARCH=' computer('arch') '"'];
    if (nargin > 0)
	args = [args sprintf(' "%s"', varargin{:})];
    end
    errCode = unix([matlabroot '/bin/mex' args]);

elseif ispc
    
    mexname = get_mex_opts(varargin{:});
    matlab_bin_location=[matlabroot '\bin'];

    if ~isempty(mexname)
        [loaded_m, loaded_mex] = inmem;
        if ~isempty(loaded_mex)
            clear_mex_file(mexname);
        end
    end
    
    % Loop over all the arguments. Put extra quotes around any that
    % contain spaces.
    for i=1:numel(varargin)
        if (find(varargin{i} == ' '))
            varargin{i} = [ '"' varargin{i} '"' ];
        end
    end
    
    % Format the mex command
    cmdargs = ['-called_from_matlab -matlab "' matlabroot '" ' sprintf(' %s', varargin{:})];
    if (any(matlab_bin_location == ' '))
        quote_str = '"';
    else
        quote_str = '';
    end

    cmdtool = [quote_str matlabroot '\sys\perl\win32\bin\perl.exe' quote_str ' ' ... 
               quote_str matlab_bin_location '\nvmex.pl' quote_str];
    [cmd, rspfile] = make_rsp_file(cmdtool, cmdargs);
    try
        errCode = dos([ cmd ' -' computer('arch') ]);
        try
            % This is done to force a change message in case
            % notificationhandles are not working properly. If it fails, we
            % just want to keep going.
            mexpath = fileparts(mexname);
            fschange(mexpath);
        catch
        end
    catch
        disp(lasterr);
        errCode = 1; % failure
    end
    delete(rspfile);
end

if (nargout > 0) 
  errorCode = errCode;
elseif (errCode ~= 0)
    errorStruct.identifier='MATLAB:MEX:genericFailure';
    errorStruct.message='Unable to complete successfully.';
    rethrow(errorStruct);
end


%%%%%%%%%%%%%%%%%%%%
%%% SUBFUNCTIONS %%%
%%%%%%%%%%%%%%%%%%%%

function result = read_response_file(filename)
%
% Read a response file (a filename that starts with '@')
% and return a cell of strings, one per entry in the response file.
% Use Perl to ensure processing of arguments is the same as mex.bat
%

result = {};

cmd = ['"' matlabroot '\sys\perl\win32\bin\perl" -e "' ...
    'require ''' matlabroot '\\sys\\perl\\win32\\lib\\shellwords.pl'';' ...
    'open(FILE, ''' filename ''') || die ''Could not open ' filename ''';' ...
    'while (<FILE>) {$line .= $_;} ' ...
    '$line =~ s/\\/\\\\/g;' ...
    '@ARGS = &shellwords($line); ' ...
    '$\" = \"\n\";' ...
    'print \"@ARGS\";'];

[s, r] = dos(cmd);

if s == 0
    cr = sprintf('\n');
    while ~isempty(r)
        [result{end+1}, r] = strtok(r, cr);
    end
end

function [mexname, setup] = get_mex_opts(varargin)
%
% GET_MEX_OPTS gets the options from the command line.
%
% name:
% It gets the name of the destination MEX-file.  This has two
% purposes: 
%   1) All platforms need to clear the MEX-file from memory before
%      attempting the build, to avoid problems rebuilding shared
%      libraries that the OS considers "in use".
%   2) Windows MATLAB deletes the MEX-file before the build occurs.
%      It then checks to see whether the MEX-file was created so as
%      to establish error status.
%   This function returns the minimum necessary information.  Further
%   processing is done on the MEX-file name by clear_mex_file to 
%   successfully clear it.
%
% setup:
% It also returns whether or not '-setup' was passed.
%

mexname = '';
outdir = '';
setup = 0;

% First, check for and expand response files into varargin.
v = {};
for count=1:nargin
    arg = varargin{count};
    if arg(1) == '@'
        new_args = read_response_file(arg(2:end));
        v(end+1:end+length(new_args)) = new_args;          
    else
        v{end+1} = arg;
    end
end

varargin = v;

count = 1;
while (count <= nargin)
    arg = varargin{count};
    if isempty(mexname) && arg(1) ~= '-' && ~any(arg=='=') && any(arg=='.')
        % Source file: MEX-file will be built in current directory
        % Only the first source file matters
        mexname = arg;
        [notUsed, mexname] = fileparts(mexname); %#ok
    elseif strcmp(arg, '-f')
        count = count + 1;
    elseif strcmp(arg, '-output')
        count = count + 1;
        if count > length(varargin)
            errorStruct.identifier = 'MATLAB:MEX:OutputSwitchMisuse';
            errorStruct.message = 'The -output switch must be followed by a file name.';
            rethrow(errorStruct);
        end
        mexname = varargin{count};
     	[outdirTemp,mexname]=fileparts(mexname);
    elseif strcmp(arg, '-outdir')
        count = count + 1;
        if count > length(varargin)
            errorStruct.identifier = 'MATLAB:MEX:OutdirSwitchMisuse';
            errorStruct.message = 'The -outdir switch must be followed by a directory name.';
            rethrow(errorStruct);
        end
        outdir = varargin{count};
    elseif strcmp(arg, '-setup')
        setup = 1;
        break;
    end
    count = count + 1;
end

if isempty(outdir) && exist('outdirTemp','var') %Meaning -ouptut
                                                %used but not -outdir
	outdir = outdirTemp;
end
mexname = fullfile(outdir, mexname);

function clear_mex_file(basename)
%
% CLEAR_MEX_FILE Clear a MEX-file from memory.  This is a tricky
%   business and should be avoided if possible.  It takes a relative
%   or absolute filename as the MEX-file name, and the list of loaded
%   MEX-file names.
%
%   If CLEAR_MEX_FILE is unable to clear the MEX-file, it will error.
%   This can happen if the MEX-file is locked.

% The purpose of following block is to make sure that fullname is a fully
% qualified path.
seps = find(basename == filesep);
if isempty(seps)
    % basename is in the current directory
    fullname = fullfile(cd,basename);
else
    % -output or -outdir was used to determine the location, as well as the
    % name of the mex file.
     savedir = cd;
     [destdir,destname] = fileparts(basename);
     cd(destdir);
     fullname = fullfile(cd,destname);
     cd(savedir);
end
	
if ~isempty(findstr(fullname, 'private'))
    % Things in private directories are represented by the full
    % path
    mexname = fullname;
else
    modifiers = find(fullname == '@');
    if any(modifiers)
        % Methods have the class directory prepended
        mexname = fullname((modifiers(end)+1):end);
        % Methods are always displayed with UNIX file
        % separators
        mexname(mexname==filesep) = '/';
    else
        % Otherwise, we just use the base name
        mexname = basename;
    end
end

clear_mex(mexname);
% Make sure that the MEX-file is cleared
[ms, mexs] = inmem;
if ~isempty(strmatch(mexname, mexs, 'exact'))
    errorStruct.identifier = 'MATLAB:MEX:mexFileLocked';
    errorStruct.message = 'Your MEX-file is locked and must be unlocked before recompiling.';
    rethrow(errorStruct);
end

function clear_mex(varargin)
% This will clear a MEX-file successfully, because it has no internal
% variables.  varargin is a builtin function and is therefore not a
% valid MEX-file name.

clear(varargin{:});

function [cmd, rspfile] = make_rsp_file(cmdtool, cmdargs)
rspfile = [tempname '.rsp'];
[Frsp, errmsg] = fopen(rspfile, 'wt');
if Frsp == -1
    errorStruct.identifier = 'MATLAB:MEX:RspFilePermissionOpen';
    errorStruct.message = sprintf('Cannot open file "%s" for writing: %s.', rspfile, errmsg);
    rethrow(errorStruct);
end
try
    count = fprintf(Frsp, '%s', cmdargs);
    if count < length(cmdargs)
        errmsg = ferror(Frsp);
        errorStruct.identifier = 'MATLAB:MEX:RspFilePermissionWrite';
        errorStruct.message = sprintf('Cannot write to file "%s": %s.', rspfile, errmsg);
        rethrow(errorStruct);
    end
    fclose(Frsp);
catch
    fclose(Frsp);
    delete(rspfile);
    rethrow(lasterror);
end

    cmd = [cmdtool ' @"' rspfile '"'];

Contact us at files@mathworks.com