Code covered by the BSD License  

Highlights from
NVIDIA CUDA-based bilinear (2D) interpolation

image thumbnail

NVIDIA CUDA-based bilinear (2D) interpolation

by

 

15 Apr 2009 (Updated )

Incredible speed boost in comparison to the Matlab implementation. (interp2)

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