Skip to content

Commit 891eaca

Browse files
authored
Improvement of AT build process (#889)
* set fp-contract to off on macOS * restore the WarningDp6D state * remove a debug printout * Handle warnings * restructured atmexall * Remove useless files
1 parent d2f764e commit 891eaca

File tree

11 files changed

+199
-220
lines changed

11 files changed

+199
-220
lines changed

.github/workflows/matlab-tests.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ jobs:
4040
- name: Atmexall
4141
uses: matlab-actions/run-command@v2
4242
with:
43-
command: run('atmat/atpath');githubsetup();
43+
command: run('atmat/atpath');githubsetup('-v');
4444

4545
- name: Build and install at
46-
run: python -m pip install .
46+
run: python -m pip install -v .
4747

4848
- name: Run tests
4949
uses: matlab-actions/run-command@v2

atintegrators/passFunctionMAC.map

-4
This file was deleted.

atintegrators/passFunctionMAC.mapext

-3
This file was deleted.

atintegrators/trackFunctionMAC.map

-4
This file was deleted.

atintegrators/trackFunctionMAC.mapext

-3
This file was deleted.

atmat/atmexall.m

+96-111
Original file line numberDiff line numberDiff line change
@@ -30,67 +30,73 @@ function atmexall(varargin)
3030
[fail,varargs]=getflag(varargs,'-fail');
3131
force=~miss_only;
3232

33-
atoptions={['-D',computer]};
33+
atoptions=[varargs {['-D',computer]}];
3434

3535
if isunix && ~ismac
3636
LIBDL={'-ldl'};
3737
else
3838
LIBDL={};
3939
end
4040

41-
ompflags={};
42-
cflags={};
41+
if isunix
42+
cflags={'-std=c99'};
43+
compformat='CFLAGS="$CFLAGS %s"';
44+
linkformat='LDFLAGS="$LDFLAGS %s"';
45+
else
46+
cflags={};
47+
compformat='COMPFLAGS="$COMPFLAGS %s"';
48+
linkformat='LINKFLAGS="$LINKFLAGS %s"';
49+
end
50+
cppflags={};
4351
ldflags={};
52+
4453
if openmp
4554
if ispc()
46-
cflags={'/openmp'};
55+
cflags=[cflags {'/openmp'}];
4756
ompflags={};
4857
elseif ismac()
49-
ompinc = select_omp();
50-
cflags={'-Xpreprocessor', '-fopenmp'};
51-
ompflags={ompinc,...
52-
sprintf('-L"%s"',fullfile(matlabroot,'sys','os',computer('arch'))),...
53-
'-liomp5'};
58+
cflags=[cflags {'-Xpreprocessor', '-fopenmp'}];
59+
ompflags = select_omp();
5460
else
55-
cflags={'-fopenmp'};
61+
cflags=[cflags {'-fopenmp'}];
5662
ompflags={...
5763
sprintf('-L"%s"',fullfile(matlabroot,'sys','os',computer('arch'))),...
5864
'-liomp5'};
5965
end
66+
else
67+
ompflags={};
6068
end
6169

70+
mexflags = make_flags(cflags, ldflags);
71+
mexcpp = make_flags(cppflags, ldflags);
6272
if ispc()
63-
ompoptions=pc_flags(ompflags, cflags, ldflags);
64-
map1=pc_flags(ompflags, cflags, ldflags);
73+
mapc=mexflags;
74+
mapcpp=mexcpp;
6575
elseif ismac()
66-
ompoptions=unix_flags(ompflags, cflags, ldflags);
67-
map1=unix_flags(ompflags, cflags, ldflags, '-Wl,-exported_symbols_list,', 'trackFunctionMAC.map');
68-
map2=unix_flags(ompflags, cflags, ldflags, '-Wl,-exported_symbols_list,', 'passFunctionMAC.map');
76+
mapc=make_flags(cflags, [ldflags {'-Wl,-exported_symbol,_trackFunction'}]);
77+
mapcpp=make_flags(cppflags, [ldflags {'-Wl,-exported_symbol,_trackFunction'}]);
6978
else
70-
ompoptions=unix_flags(ompflags, cflags, ldflags);
71-
map1=unix_flags(ompflags, cflags, ldflags, '-Wl,--version-script,', 'mexFunctionGLNX86.map');
79+
exportflag = sprintf('VERSIONMAP="%s"',fullfile(pdir, 'mexFunctionGLNX86.mapext'));
80+
mapc=[mexflags {exportflag, 'LINKEXPORT=""'}];
81+
mapcpp=[mexcpp {exportflag, 'LINKEXPORT=""'}];
7282
end
7383

74-
try
75-
if ~verLessThan('matlab','9.4') % >= R2018a
76-
atoptions = [atoptions,{'-R2018a'}];
77-
elseif ~verLessThan('matlab','7.11') % >= R2010b
78-
atoptions = [atoptions,{'-largeArrayDims'}];
79-
end
80-
if ~verLessThan('matlab','8.3') % >= R2014a
81-
atoptions = [atoptions,{'-silent'}];
82-
end
83-
catch
84+
if ~verLessThan('matlab','9.4') % >= R2018a
85+
atoptions = [atoptions,{'-R2018a'}];
86+
elseif ~verLessThan('matlab','7.11') % >= R2010b
87+
atoptions = [atoptions,{'-largeArrayDims'}];
88+
end
89+
if ~verLessThan('matlab','8.3') % >= R2014a
90+
atoptions = [atoptions,{'-silent'}];
8491
end
8592

8693
lastwarn('');
8794
passinclude = ['-I' pdir];
88-
alloptions=[atoptions varargs];
8995

9096
% atpass
9197
cdir=fullfile(atroot,'attrack','');
92-
compile([alloptions, {passinclude}, LIBDL, ompoptions], fullfile(cdir,'atpass.c'));
93-
compile([atoptions, ompoptions],fullfile(cdir,'coptions.c'))
98+
compile([atoptions, {passinclude}, LIBDL, mexflags, ompflags], fullfile(cdir,'atpass.c'));
99+
compile([atoptions, mexflags, ompflags],fullfile(cdir,'coptions.c'))
94100

95101
[warnmess,warnid]=lastwarn; %#ok<ASGLU>
96102
if strcmp(warnid,'MATLAB:mex:GccVersion_link')
@@ -100,73 +106,65 @@ function atmexall(varargin)
100106

101107
% Diffusion matrices
102108
cdir=fullfile(atroot,'atphysics','Radiation');
103-
compile([alloptions, {passinclude}], fullfile(cdir,'findmpoleraddiffmatrix.c'));
104-
compile([alloptions, {passinclude}], fullfile(cdir,'FDW.c'));
105-
compile([alloptions, {passinclude}, LIBDL], fullfile(cdir,'diffusion_matrix.c'));
109+
compile([atoptions, {passinclude}, mexflags], fullfile(cdir,'findmpoleraddiffmatrix.c'));
110+
compile([atoptions, {passinclude}, mexflags], fullfile(cdir,'FDW.c'));
111+
compile([atoptions, {passinclude}, LIBDL, mexflags], fullfile(cdir,'diffusion_matrix.c'));
106112

107113
% RDTs
108114
cdir=fullfile(atroot,'atphysics','NonLinearDynamics');
109-
compile(alloptions, fullfile(cdir,'RDTelegantAT.cpp'));
115+
compile([atoptions, mexcpp], fullfile(cdir,'RDTelegantAT.cpp'));
110116

111117
% NAFF
112118
cdir=fullfile(atroot,'atphysics','nafflib');
113-
compile(alloptions, fullfile(cdir,'nafflib.c'),...
114-
fullfile(cdir,'modnaff.c'),...
115-
fullfile(cdir,'complexe.c'));
119+
compile([atoptions, mexflags], fullfile(cdir,'nafflib.c'),...
120+
fullfile(cdir,'modnaff.c'),...
121+
fullfile(cdir,'complexe.c'));
116122

117-
% Find all files matching '*Pass.c' wildcard
118-
cfiles = dir(fullfile(pdir,'*Pass.c'));
119-
passmethods = {cfiles.name};
123+
% Passmethods
124+
cfiles = passcomp(pdir, '*Pass.c',[atoptions, mapc, ompflags]);
120125
if ~c_only
121-
% Find all files matching '*Pass.cc' wildcard
122-
ccfiles = dir(fullfile(pdir, '*Pass.cc'));
123-
passmethods = [passmethods ccfiles.name];
126+
% Compile '*Pass.cc' methods
127+
ccfiles = passcomp(pdir, '*Pass.cc',[atoptions, mapcpp, ompflags]);
128+
else
129+
ccfiles={};
124130
end
125-
% Eliminate invisible files
126-
ok=cellfun(@(nm) nm(1)~='.',passmethods,'UniformOutput',false);
127-
passmethods = passmethods(cell2mat(ok));
131+
128132
try
129-
generate_passlist(pdir,passmethods);
133+
generate_passlist(pdir,[cfiles ccfiles]);
130134
catch err
131135
fprintf(2,'\nCannot generate the list of passmethods: %s\n\n', err.message);
132136
end
133137

134-
for i = 1:length(passmethods)
135-
PM = fullfile(pdir,[passmethods{i}]);
136-
if exist(PM,'file')
137-
try
138-
if exist('map2','var')
139-
try
140-
compile([map1, alloptions], PM);
141-
catch
142-
compile([map2, alloptions], PM);
138+
warning(oldwarns.state,oldwarns.identifier);
139+
140+
function meths=passcomp(pdir, pattern, compargs)
141+
meths = dir(fullfile(pdir,pattern));
142+
% Keep the names
143+
meths = {meths.name};
144+
% Discard hidden files
145+
meths = meths(cellfun(@(nm) nm(1)~='.',meths));
146+
for im=1:length(meths)
147+
pmeth = fullfile(pdir,[meths{im}]);
148+
try
149+
compile(compargs, pmeth);
150+
catch errcomp
151+
if fail
152+
rethrow(err);
153+
else
154+
fprintf(2, 'Could not compile %s:\n%s\n', pmeth, errcomp.message);
143155
end
144-
else
145-
compile([map1, alloptions], PM);
146-
end
147-
catch err
148-
if fail
149-
rethrow(err);
150-
else
151-
fprintf(2, 'Could not compile %s:\n%s\n', PM, err.message);
152156
end
153157
end
154-
else
155-
if fail
156-
error('AT:atmexall', '%s not found\n', PM);
157-
else
158-
fprintf(2,'%s not found, skip to next\n', PM);
158+
% Remove extension
159+
meths = cellfun(@dpl,meths, 'UniformOutput',false);
160+
161+
function nm=dpl(fname)
162+
[~,nm,~] = fileparts(fname);
159163
end
160164
end
161-
end
162165

163-
warning(oldwarns.state,oldwarns.identifier);
164166

165-
function generate_passlist(pdir,passmethods)
166-
% Remove trailing '.c' or '.cc' from each passmethod using regexp
167-
% Literally, replace dot plus any number of cs at the end of a
168-
% passmethod with an empty string.
169-
passmethodnames = cellfun(@(pass) regexprep(pass, '\.c*$', ''),passmethods, 'UniformOutput', false);
167+
function generate_passlist(pdir,passmethodnames)
170168
[fid,msg]=fopen(fullfile(pdir,'passmethodlist.m'),'wt');
171169
if ~isempty(msg)
172170
error(msg);
@@ -179,40 +177,15 @@ function generate_passlist(pdir,passmethods)
179177
nbytes=cellfun(@(pass) fprintf(fid,'%s\n',pass),passmethodnames); %#ok<NASGU>
180178
fprintf(fid,'\nend\n');
181179
fclose(fid);
182-
end
180+
end
183181

184-
function flags=pc_flags(flags, cflags,ldflags)
182+
function flags=make_flags(cflags, ldflags)
183+
flags = {};
185184
if ~isempty(ldflags)
186-
flags=[{sprintf('LINKFLAGS="$LINKFLAGS %s"',strjoin(ldflags))}, flags];
185+
flags = [{sprintf(linkformat,strjoin(ldflags))} flags];
187186
end
188187
if ~isempty(cflags)
189-
flags=[{sprintf('COMPFLAGS="$COMPFLAGS %s"',strjoin(cflags))}, flags];
190-
end
191-
end
192-
193-
194-
function flags=unix_flags(flags, cflags, ldflags, exportarg, map)
195-
if nargin > 3
196-
mapfile=fullfile(pdir, map);
197-
if verLessThan('matlab','8.3') % R2008a < < R2014a
198-
exp=sprintf([exportarg '"%s"'], mapfile);
199-
def_ldflags=regexprep(mex.getCompilerConfigurations('C').Details.LinkerFlags,['\s(' exportarg ')([^\s,]+)'],'');
200-
flags=[{sprintf('LDFLAGS=%s',strjoin([{def_ldflags}, ldflags, {exp}]))}, flags];
201-
ldflags = {};
202-
elseif verLessThan('matlab','9.1') % < R2016b
203-
flags=[{sprintf('LINKEXPORT=%s"%s"',exportarg,mapfile)}, flags];
204-
else % >= R2016b
205-
% Starting from R2016b, Matlab introduced a new entry point in MEX-files
206-
% The "*.mapext" files defines this new entry point
207-
flags=[{sprintf('VERSIONMAP="''%sext''"',mapfile),...
208-
sprintf('FUNCTIONMAP="''%s''"',mapfile)}, flags];
209-
end
210-
end
211-
if ~isempty(ldflags)
212-
flags = [{sprintf('LDFLAGS="$LDFLAGS %s"',strjoin(ldflags))} flags];
213-
end
214-
if ~isempty(cflags)
215-
flags=[{sprintf('CFLAGS="$CFLAGS %s"',strjoin(cflags))}, flags];
188+
flags = [{sprintf(compformat,strjoin(cflags))} flags];
216189
end
217190
end
218191

@@ -221,7 +194,6 @@ function compile(mexargs, varargin)
221194
target = strjoin({fullfile(fpath, fname), mexext}, '.');
222195
if force || ~exist(target, 'file') || ...
223196
any(cellfun(@(f) getdate(f) > getdate(target), varargin))
224-
% any(cellfun(@(f) dir(f).datenum > dir(target).datenum, varargin)) % Not accepted in R2016b
225197
disp(['mex ',strjoin([mexargs, {'-outdir', fpath}, varargin])]);
226198
mex(mexargs{:},'-outdir', fpath, varargin{:});
227199
end
@@ -232,17 +204,30 @@ function compile(mexargs, varargin)
232204
end
233205
end
234206

235-
function include=select_omp()
236-
if exist('/usr/local/include/omp.h', 'file') % Homebrew
237-
include='-I/usr/local/include';
207+
function flags=select_omp()
208+
arch=computer('arch');
209+
if strcmp(arch, 'maca64')
210+
homeb='/opt/homebrew/opt/libomp/include';
211+
libdir=fullfile(matlabroot,'bin',arch);
212+
libname='omp';
213+
else
214+
homeb='/usr/local/include';
215+
libdir=fullfile(matlabroot,'sys','os',arch);
216+
libname='iomp5';
217+
end
218+
if exist([homeb '/omp.h'], 'file') % Homebrew
219+
incdir=homeb;
238220
elseif exist('/opt/local/include/libomp/omp.h', 'file') % MacPorts
239-
include='-I/opt/local/include/libomp';
221+
incdir='/opt/local/include/libomp';
222+
libdir='/opt/local/lib';
223+
libname='omp';
240224
else
241225
error('AT:MissingLibrary', strjoin({'', ...
242226
'libomp.dylib must be installed with your favourite package manager:', '', ...
243227
'Use "$ brew install libomp"', ...
244228
'Or "$ sudo port install libomp"'...
245229
}, '\n'));
246230
end
231+
flags={['-I' incdir], sprintf('-L"%s"',libdir),['-l' libname]};
247232
end
248233
end

atmat/atphysics/TuneAndChromaticity/findtune.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
for bpm=reject
7070
fprintf('rejected BPM %d\n', bpm);
7171
end
72-
fprintf('%20s tune:%g (rms:%g)\n',methname, mean(tune(keep),2),std(tune(keep),0,2));
72+
% fprintf('%20s tune:%g (rms:%g)\n',methname, mean(tune(keep),2),std(tune(keep),0,2));
7373

7474
function vv=phi(a,b,c) %#ok<DEFNU>
7575
d1=c*(a+b);

atmat/atphysics/atavedata.m

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@
2626
needed=refs | [false;long]; %lr
2727
initial=[long(needed(1:end-1));false]; %needed
2828
final=[false;initial(1:end-1)]; %needed
29-
setoption('WarningDp6D',false)
29+
wstate=getoption('WarningDp6D');
30+
setoption('WarningDp6D',false);
3031
[ringdata, lind]=atlinopt6(ring,needed,'dp',dpp,'get_chrom',varargin{:}); %needed
31-
setoption('WarningDp6D',true)
32+
setoption('WarningDp6D',wstate);
3233
nu = ringdata.tune;
3334
xsi = ringdata.chromaticity;
3435

atmat/attests/githubsetup.m

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
function githubsetup()
1+
function githubsetup(varargin)
22
%GITHUBSETUP Private. Setup Matlab for AT tests in GitHib Actions
33
%
44
% This function prepares a workflow in GitHub actions for using AT and
55
% calling python from Matlab. There is normally no reason to use it in a
66
% user workflow.
77

88
savepath('pathdef.m');
9-
atmexall -fail
9+
mex -setup
10+
mex -setup C++
11+
atmexall('-fail', varargin{:});
1012
if ispc
1113
execfile=fullfile(getenv('pythonLocation'),'pythonw.exe');
1214
else

0 commit comments

Comments
 (0)