Create Mex files for Matlab, from .FOR files of Fortran
Ältere Kommentare anzeigen
Hello. there are files with the .FOR extension, in which the subroutine codes are written in the Fortran language. I want to create Mex files from these files, which can be run in matlab. how to do it?
Antworten (4)
Which OS? For Linux, the GNU Fortran compiler is supported, for Windows and Mac only a recent version of the Intel compiler is supported.
It's unconscionable that TMW supports GNU for Linux but not for Windows and Mac; I, at least, have had no success in figuring out how to link although since it supports the GNU C compiler that the Fortran compiler is built on, it surely should be possible -- excepting for the name-mangling issues.
And, TMW has essentially quit supporting Fortran at all; the example files are still horribly outdated F77-style fixed-format with archaic at best non-standard syntax and other style problems.
You probably have a real challenge on your hands; the alternative may be to write interface routines in C and then have those call the Fortran code instead of trying to build direct Fortran mex interfaces.
@James Tursa is the real guru; hopefully he'll see and comment and have better pointers; my patience was exhausted some years ago and, fortunately, the need for additional support for the application I supported for a client while still consulting has, apparently, either gone away or they've found an alternate way so I've just given up.
James Tursa
am 12 Aug. 2023
Bearbeitet: James Tursa
am 12 Aug. 2023
0 Stimmen
So, I haven't had access to a Fortran compiler in over 10 years. And as a result I haven't been maintaining any of my Fortran FEX submissions. Kinda sad that this very fast matrix/array based language with the same memory-element order as MATLAB does not have free solutions for connecting with MATLAB, at least not for Windows, but that's the way it is. And @dpb, the Fortran examples supplied by TMW still have the same bugs in them, and the compile files probably still have the stupid /fixed option (forces free form source code to be compiled as fixed form source code ... generating lots of faux errors), that I pointed out over 10 years ago. I just submitted another request that they change this. Sigh ...
My suggestion depends on what your Fortran code does, and whether it has user I/O. If it is just number crunching, I would probably use whatever Fortran compiler you have to create .obj files. Then write a simple wrapper mex file in C that acts as a conduit for the input & output variables. Then just mex the wrapper C file and Fortran .obj files together.
If your code has user I/O, that is a whole different ball game ...
So, what does your Fortran code do? What are the inputs and outputs? Can you post the interface function signatures for us? Maybe we can quickly write the wrapper code for you.
13 Kommentare
Indeed...I really wasn't aware of actual bugs in the examples; I think the "timestwo" is about the only one I ever looked at early on to test the link actually work initially for each new install. But, given the state of the rest, it's not surprising to me there would be.
And, yes, I complained and filed "enhancement" requests to fix the hardcoded /fixed option multiple times as well "way back when"; all ignored, obviously.
If they would just document the link step and let folks build directly instead of obfuscating the process behind all the scripts, it could be much simpler and a mortal might have a chance at actually getting something to work -- but, no, they refuse to do even that much.
Mostly MATLAB is a great product, but there are a few things TMW does that are just frustrating beyond belief -- this is one.
James Tursa
am 14 Aug. 2023
Bearbeitet: James Tursa
am 14 Aug. 2023
timestwo.f is one of the routines that used to have bugs. It accepted non-scalar inputs but there was some dimensions or allocations related code that only worked for scalars. So non-scalar inputs were likely to generate a seg fault for invalid memory access. I just looked at R2023a and they have fixed that particular bug, finally. Although they still use a literal 0 constant in a call to an API routine ... a definite no-no in Fortran. They also don't check for sparsity or double type etc. Bottom line is I think I could still get this routine to crash MATLAB.
dpb
am 14 Aug. 2023
I'm sure I never tried to stress timestwo, simply made sure it ran the simple test of timestwo(2,3) and called it good enough to check compiler setup.
James Tursa
am 14 Aug. 2023
Bearbeitet: James Tursa
am 14 Aug. 2023
@dpb I just checked this page:
Look at Intel oneAPI for Fortran (2021,2022,2023). Do you know anything about these? I haven't tried, but it looks like they may be free? Is this a full compiler or just a toolbox for a paid compiler? I may have to retract my statement about no free Fortran compiler for Windows. See here:
Maybe I can get back into Fortran ...
dpb
am 14 Aug. 2023
I had received something about OneAPI from Intel quite a long time ago (years, not months), but afac(ould)t at the time it was just a reconfiguration, not a change in licensing/cost.
By that time I had installed gcc and what Fortran I needed at the time was standalone rather than MEX and I hadn't paid attention since.
I had heard some rumors but hadn't checked it out; one would think TMW would have a footnote in their requirements about accessiblility, but I supose they feel that's "not their job!".
I still think it silly and a slap in face to not support gcc on the Windows side since they do already have the work done for the other OS'es.
Of course, that they've not extended the API to cover all the newer stuff on the Fortran side also makes it the red-haired stepchild and second-class citizen, but having an interface at all would be a big deal, indeed.
I'm buried to above my eyebrows in another pro bono task for local college foundation that I've simply got to wrap up before I can get sidetracked seeing about this, though...
If you have the time/inclination and have any success along this route, though, James, be sure to post what it took to get it going.
roborrr
am 15 Aug. 2023
dpb
am 15 Aug. 2023
Intel Parallel Studio is not free and as information in the posting at the link @James Tursa posted says, is past its support lifetime.
Pasted from that link:
"Parallel Studio XE" as a product and software package is end of life. There will be no more PSXE product releases.
Released products ended with PSXE 2020 Update 4 in October 2020. So no updates coming for PSXE.
We put ifort and ifx into our oneAPI packages today, started with oneAPI 2021. So if you want the latest ifort, it's in the oneAPI packages, specifically the HPC Toolkit, or this stand-alone component download.
This includes support for current Visual Studio versions.
Yes, to get our new versions of Intel Fortran you need to now download oneAPI packages."
AFAICT, there is no public link on the Intel site to PSXE any more; only to OneAPI.
I was unaware the OneAPI suite had been made free to access, see again the second link above for information on downloading/installing it. NOTA BENE: You MUST independently download/install a compatible version of the MS Visual Studio environment for it to work; that appears sometimes to be no mean feat in itself.
As I noted above in reply back to James, I'm bogged down in another task at the moment besides having had the desktop machine die so have only the laptop at the moment. So, I've not got the time to get sidetracked chasing this down at the moment.
Good luck, let us know how it goes...
roborrr
am 16 Aug. 2023
James Tursa
am 16 Aug. 2023
Bearbeitet: James Tursa
am 16 Aug. 2023
Just downloaded the free Fortran compiler from the above link and it works! WinPC R2023a. Had to remove the silly /fixed option in the xml files to get the .f90 free format files to work, and fixed format had to use .f instead of .for, but it works! I integrated it with my MSVS 2022, but the installation said this was optional, so it may still have worked without doing that. From this link:
Just pick the installation you want and click. Installed pretty quickly for me.
Sooooo ... I have to retract everything I said above about there not being a free Fortran compiler for Windows that is supported by MATLAB. (THANKS TMW!)
dpb
am 16 Aug. 2023
Thanks particularly to Intel for releasing the compiler for open access and use...no idea if TMW had any influence in that decision or not.
. One of them contains the main program. From these files, you need to create mex files that are readable in Matlab."
MATLAB mex files are not fully executable programs; in fact, a mex file CANNOT have a program module that will link the executable startup code; simply will not work that way. Everything has to be a callable subroutine and there is a <gateway mex function> that is what MATLAB actually calls behind the scenes that handles the interface between MATLAB and the Fortran code that you create as the mex function and call from MATLAB.
If you have a complete fortran code to run, the better path is probably to simply compile/link it and then, perhaps, run it from MATLAB by using the system command. How you could control input and return output will depend upon how the code itself is written.
But, thinking you're just going to have it all integrated into MATLAB essentially transparently just by trying to mex the existing fortran code is not the correct model/concept.
You've not shared enough about the code nor your actual objectives/reason for MATLAB being in the mix to know, specifically, what you might be able to do to accomplish those goals, but you don't seem to have the right concept of what mex files are nor how they interface between MATLAB and the other language, whether that's Fortran, C, C++.
The above seems peculiar, <the Intel doc> still says that .f and .for are both assumed by the compiler to be fixed format source form (as well as .ftn and .i).
While the /fixed switch is there in the shipped .xml files, if you've removed it, then I wonder where TMW has managed to override that behavior in the mex configuration scripts -- stuff like that that is so obfuscated is what finally drove me nuts and to just give up when couldn't still use the old CVF compiler which wouldn't run on the 64-bit OS since no longer had a paying client to foot the bills and make the effort worthwhile other than just having the facility when wanted it.
Hmmmm....does it somehow have something to do with the preprocessor, maybe? I never got into the habit of preprocessing Fortran files but mex does it automagically because the include files have lot of #defines in them for type definitions, etc., ... I hate their style, but it is what it is.
Well, I download/installed, too, and mex -setup fails to find the Intel 2023 compiler...it's installed and works as
C:\Users\owner>ifx hello.f90
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2023.2.0 Build 20230627
Copyright (C) 1985-2023 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 14.29.30151.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:hello.exe
-subsystem:console
hello.obj
C:\Users\owner>hello
Hello, world!
C:\Users\owner>
illustrates, but
>> strvcat(supported.MexOpt)
ans =
10×58 char array
'C:\ML_R2021b\bin\win64\mexopts\intel_fortran_18_vs2015.xml'
'C:\ML_R2021b\bin\win64\mexopts\intel_fortran_18_vs2017.xml'
'C:\ML_R2021b\bin\win64\mexopts\intel_fortran_18_vs2019.xml'
'C:\ML_R2021b\bin\win64\mexopts\intel_fortran_19_vs2015.xml'
'C:\ML_R2021b\bin\win64\mexopts\intel_fortran_19_vs2017.xml'
'C:\ML_R2021b\bin\win64\mexopts\intel_fortran_19_vs2019.xml'
'C:\ML_R2021b\bin\win64\mexopts\intel_fortran_20_vs2017.xml'
'C:\ML_R2021b\bin\win64\mexopts\intel_fortran_20_vs2019.xml'
'C:\ML_R2021b\bin\win64\mexopts\intel_fortran_21_vs2017.xml'
'C:\ML_R2021b\bin\win64\mexopts\intel_fortran_21_vs2019.xml'
>> mex -setup FORTRAN
Error using mex
Supported compiler not detected. For options, visit https://www.mathworks.com/support/compilers.
>>
I've no klew at this point yet as to how to make it find it...I'm pretty sure it must have to do with where/how mex searches, but they give no hints as to how that does/does not work in order to be able to prod it in the right direction.
I let the install use the default location...
I dunno, did you use VS and build inside it instead, maybe? I've never tried that; always just wrote code with my preferred toolset and then compiled/linked. W/ CVF in the olden days I could do all that inside the Brief editor but it also won't run on these systems any more, sadly.
6 Kommentare
Run
>> supported=mex.getCompilerConfigurations('Fortran','Supported');
>> strvcat(supported.Name)
ans =
10×75 char array
'Intel Parallel Studio XE 2018 for Fortran with Microsoft Visual Studio 2015'
'Intel Parallel Studio XE 2018 for Fortran with Microsoft Visual Studio 2017'
'Intel Parallel Studio XE 2018 for Fortran with Microsoft Visual Studio 2019'
'Intel Parallel Studio XE 2019 for Fortran with Microsoft Visual Studio 2015'
'Intel Parallel Studio XE 2019 for Fortran with Microsoft Visual Studio 2017'
'Intel Parallel Studio XE 2019 for Fortran with Microsoft Visual Studio 2019'
'Intel Parallel Studio XE 2020 for Fortran with Microsoft Visual Studio 2017'
'Intel Parallel Studio XE 2020 for Fortran with Microsoft Visual Studio 2019'
'Intel oneAPI 2021 for Fortran with Microsoft Visual Studio 2017 '
'Intel oneAPI 2021 for Fortran with Microsoft Visual Studio 2019 '
>>
Unless your install includes one of the precise combinations shown for your system, the mex setup script will fail.
There is a .xml file to match each of those, but the install has to also be in a location that the script is smart enough to look and be able to find. See mex.getCompilerConfigurations for details. There's a define in the .xml file for the compiler location $FORTRANROOT where it expects the installation to be; I'm not positive who is responsible for defining that variable; at the moment, while I do have mingw64\gfortran on this machine, that variable doesn't exist in the environment so even if there were an .xml file for gfortran in the mexopts folder, the lookup would fail. Another thing to try in MATLAB command window would be
getenv('FORTRANROOT')
and see what it shows.
In particular, look at the .Details field for the particular combination you have (or think you have) installed and see if that detail matches the actual installation.
This setup in extremely convoluted and virtually impossible to figure out how it's all put together, but there's the root of all...
But, try running
mex -setup Fortran
before trying to compile something and see if it will find the compiler.
Read mex
supported=mex.getCompilerConfigurations('FORTRAN','Supported');
strvcat(supported.Name)
For the online system on a Linux system, it is gfortran only...
James Tursa
am 16 Aug. 2023
Well, have you installed the gfortran compiler?
It's on this machine,yes. I used the TMW-supplied optional add-ons link to do the download/install rather than a manual install. It ended up in a location under \Users\All\... with a MATLAB folder that makes it appear gfortran came along for the ride.
The .xml files for it have $MINGWROOT but it isn't defined in them; the location environment variable that is set is
MW_MINGW64_LOC=C:\ProgramData\MATLAB\SupportPackages\R2021b\3P.instrset\mingw_w64.instrset
The C compiler is setup and works with/inside MATLAB...
>> mex -setup C
MEX configured to use 'MinGW64 Compiler (C)' for C language compilation.
>>
The MW_MINGW64_LOC variable is clearly something MATLAB install did, but the behind the scenes magic that the mex -setup call does using the .xml files is hidden. It used to be one could try to plow one's way through the convoluted mex m-file; now they've completely hidden that as well; it's a builtin function so there's no klew whatsoever. I dunno if they are stll using those other scripts as well that it used to spawn. Like so many things, if it "just works", it's ok, but if/when it doesn't, trying to debug what went wrong is a nightmare.
I can compile/link from the command line with gfortran but there's no support for it with mex files; I spent some time a couple years ago trying to make that work and was never able to solve the name-mangling issues on linking to the TMW libraries even though I did (I think I recall) manage to create an .xml file that mex thought meant the gfortran compiler was installed.
At that time I still thought all the Intel compilers were still commercial-licenses only and so never looked at them.
I still think it should be possible since they can link with gcc and gfortran is simply a frontend for it. I knew how to write the pragmas with CVF to handle the name-mangling, but never got far enough along to figure out how to do the same thing with gfortran/gcc.
I asked on Answers then if there were enough interest to form a group to try to build the package but got no responses and got too involved in other things to pursue it. That's been at least two, probably three or maybe even more years ago by now.
dpb
am 16 Aug. 2023
Actually one can see the switches used for gfortran on the unix platform using the above; but I couldn't figure out a way to get a copy of the saved struct variable to a local file from the remote platform to be able to poke at it in a more leisurely fashion. At some point, might retry that exercise again with that guiding light...
dpb
am 17 Aug. 2023
@dpb wrote earlier "There's a define in the .xml file for the compiler location $FORTRANROOT where it expects the installation to be; I'm not positive who is responsible for defining that variable;"
Aha! I just found it; I had quite scrolling in the .xml files after the compiler/linker definitions; there's a very convoluted search logic written in xml as
<locationFinder>
<FORTRANROOT>
<or>
<and>
<or>
<envVarExists name="IFORT_COMPILER22" />
</or>
<fileExists name="$$/Bin/intel64/ifort.exe" />
<dirExists name="$$/../.." />
</and>
<and>
<or>
<envVarExists name="ONEAPI_ROOT" />
</or>
<fileExists name="$$/compiler/latest/windows/Bin/intel64/ifort.exe" />
<dirExists name="$$/../.." />
</and>
<and>
<or>
<envVarExists name="ONEAPI_ROOT" />
</or>
<fileExists name="$$/compiler/2021.1.1/windows/Bin/intel64/ifort.exe" />
<dirExists name="$$/../.." />
</and>
</or>
</FORTRANROOT>
<VCROOT>
<or>
<and>
<envVarExists name="ProgramFiles(x86)" />
<fileExists name="$$\Microsoft Visual Studio\Installer\vswhere.exe" />
<cmdReturns name=""$$\\vswhere.exe" -version "[16.0,18.0)" -products Microsoft.VisualStudio.Product.Enterprise -property installationPath -format value" />
<cmdReturns name="set "vcroot=$$"&for /f "delims= " %a in ('type "$$\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt"') do @if exist "$$\VC\Tools\MSVC\%a\bin\HostX64\x64\cl.exe" call echo %vcroot%" />
</and>
<and>
<envVarExists name="ProgramFiles(x86)" />
<fileExists name="$$\Microsoft Visual Studio\Installer\vswhere.exe" />
<cmdReturns name=""$$\\vswhere.exe" -version "[16.0,18.0)" -products Microsoft.VisualStudio.Product.Professional -property installationPath -format value" />
<cmdReturns name="set "vcroot=$$"&for /f "delims= " %a in ('type "$$\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt"') do @if exist "$$\VC\Tools\MSVC\%a\bin\HostX64\x64\cl.exe" call echo %vcroot%" />
</and>
<and>
<envVarExists name="ProgramFiles(x86)" />
<fileExists name="$$\Microsoft Visual Studio\Installer\vswhere.exe" />
<cmdReturns name=""$$\\vswhere.exe" -version "[16.0,18.0)" -products Microsoft.VisualStudio.Product.Community -property installationPath -format value" />
<cmdReturns name="set "vcroot=$$"&for /f "delims= " %a in ('type "$$\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt"') do @if exist "$$\VC\Tools\MSVC\%a\bin\HostX64\x64\cl.exe" call echo %vcroot%" />
</and>
</or>
</VCROOT>
<SDKROOT>
<or>
<hklmExists path="SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0" name="InstallationFolder" />
<hkcuExists path="SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0" name="InstallationFolder" />
<hklmExists path="SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0" name="InstallationFolder" />
<hkcuExists path="SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v10.0" name="InstallationFolder" />
</or>
</SDKROOT>
<VSINSTALLDIR>
<or>
<and>
<envVarExists name="ProgramFiles(x86)" />
<fileExists name="$$\Microsoft Visual Studio\Installer\vswhere.exe" />
<cmdReturns name=""$$\\vswhere.exe" -version "[16.0,18.0)" -products Microsoft.VisualStudio.Product.Enterprise -property installationPath -format value" />
</and>
<and>
<envVarExists name="ProgramFiles(x86)" />
<fileExists name="$$\Microsoft Visual Studio\Installer\vswhere.exe" />
<cmdReturns name=""$$\\vswhere.exe" -version "[16.0,18.0)" -products Microsoft.VisualStudio.Product.Professional -property installationPath -format value" />
</and>
<and>
<envVarExists name="ProgramFiles(x86)" />
<fileExists name="$$\Microsoft Visual Studio\Installer\vswhere.exe" />
<cmdReturns name=""$$\\vswhere.exe" -version "[16.0,18.0)" -products Microsoft.VisualStudio.Product.Community -property installationPath -format value" />
</and>
</or>
</VSINSTALLDIR>
<VCINSTALLDIR>
<or>
<and>
<envVarExists name="ProgramFiles(x86)" />
<fileExists name="$$\Microsoft Visual Studio\Installer\vswhere.exe" />
<cmdReturns name=""$$\\vswhere.exe" -version "[16.0,18.0)" -products Microsoft.VisualStudio.Product.Enterprise -property installationPath -format value" />
<cmdReturns name="set "vcroot=$$"&for /f "delims= " %a in ('type "$$\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt"') do @if exist "$$\VC\Tools\MSVC\%a\bin\HostX64\x64\cl.exe" call echo %vcroot%\VC\Tools\MSVC\%a" />
</and>
<and>
<envVarExists name="ProgramFiles(x86)" />
<fileExists name="$$\Microsoft Visual Studio\Installer\vswhere.exe" />
<cmdReturns name=""$$\\vswhere.exe" -version "[16.0,18.0)" -products Microsoft.VisualStudio.Product.Professional -property installationPath -format value" />
<cmdReturns name="set "vcroot=$$"&for /f "delims= " %a in ('type "$$\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt"') do @if exist "$$\VC\Tools\MSVC\%a\bin\HostX64\x64\cl.exe" call echo %vcroot%\VC\Tools\MSVC\%a" />
</and>
<and>
<envVarExists name="ProgramFiles(x86)" />
<fileExists name="$$\Microsoft Visual Studio\Installer\vswhere.exe" />
<cmdReturns name=""$$\\vswhere.exe" -version "[16.0,18.0)" -products Microsoft.VisualStudio.Product.Community -property installationPath -format value" />
<cmdReturns name="set "vcroot=$$"&for /f "delims= " %a in ('type "$$\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt"') do @if exist "$$\VC\Tools\MSVC\%a\bin\HostX64\x64\cl.exe" call echo %vcroot%\VC\Tools\MSVC\%a" />
</and>
</or>
</VCINSTALLDIR>
<VCVARSALLDIR>
<or>
<and>
<envVarExists name="ProgramFiles(x86)" />
<fileExists name="$$\Microsoft Visual Studio\Installer\vswhere.exe" />
<cmdReturns name=""$$\\vswhere.exe" -version "[16.0,18.0)" -products Microsoft.VisualStudio.Product.Enterprise -property installationPath -format value" />
<fileExists name="$$\VC\Auxiliary\Build\vcvarsall.bat" />
<dirExists name="$$"/>
</and>
<and>
<envVarExists name="ProgramFiles(x86)" />
<fileExists name="$$\Microsoft Visual Studio\Installer\vswhere.exe" />
<cmdReturns name=""$$\\vswhere.exe" -version "[16.0,18.0)" -products Microsoft.VisualStudio.Product.Professional -property installationPath -format value" />
<fileExists name="$$\VC\Auxiliary\Build\vcvarsall.bat" />
<dirExists name="$$"/>
</and>
<and>
<envVarExists name="ProgramFiles(x86)" />
<fileExists name="$$\Microsoft Visual Studio\Installer\vswhere.exe" />
<cmdReturns name=""$$\\vswhere.exe" -version "[16.0,18.0)" -products Microsoft.VisualStudio.Product.Community -property installationPath -format value" />
<fileExists name="$$\VC\Auxiliary\Build\vcvarsall.bat" />
<dirExists name="$$"/>
</and>
</or>
</VCVARSALLDIR>
<KITSROOT>
<or>
<hklmExists path="SOFTWARE\Wow6432Node\Microsoft\Windows Kits\Installed Roots" name="KitsRoot10" />
<hkcuExists path="SOFTWARE\Wow6432Node\Microsoft\Windows Kits\Installed Roots" name="KitsRoot10" />
<hklmExists path="SOFTWARE\Microsoft\Windows Kits\Installed Roots" name="KitsRoot10" />
<hkcuExists path="SOFTWARE\Microsoft\Windows Kits\Installed Roots" name="KitsRoot10" />
</or>
</KITSROOT>
<SDKVERSION>
<and>
<or>
<hklmExists path="SOFTWARE\Wow6432Node\Microsoft\Windows Kits\Installed Roots" name="KitsRoot10" />
<hkcuExists path="SOFTWARE\Wow6432Node\Microsoft\Windows Kits\Installed Roots" name="KitsRoot10" />
<hklmExists path="SOFTWARE\Microsoft\Windows Kits\Installed Roots" name="KitsRoot10" />
<hkcuExists path="SOFTWARE\Microsoft\Windows Kits\Installed Roots" name="KitsRoot10" />
</or>
<!-- For each folder inside '<KITSROOT>\include' check for 'ucrt' and if exists return that folder name -->
<cmdReturns name="echo off&set "sdkversion="&(for /f %a IN ('dir "$$\include\" /b /ad-h /on') do ( @if exist "$$\include\%a\ucrt\" set "sdkversion=%a" ))&call echo %sdkversion%" />
</and>
</SDKVERSION>
</locationFinder>
The above has buried in it expected install paths and version numbers; I've yet to dive totally into the constants here but looks like one copy of the ifort.exe compiler on the installed path should match this expected one; the ONEAPI_ROOT environment variable is set. The version returned is
C:\Program Files (x86)\Intel\oneAPI\compiler\latest\windows\bin\intel64>ifort
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.10.0 Build 20230609_000000
which returns 2021.10 as a version whereas the xml file just says "21.0". I'm not sure if that's an/the issue or not or whether the fact it installed in a folder ..\2023.2.1 instead of ..\2021.1.1 that's buried in the script. Although superfiically it looks like it should have matched the earlier <or> under "../latest/windows/Bin/intel64/" because there's a copy of ifort.exe there, too.
Why they have to make this so complicated...and give no diagnostics nor ways to fix if something does go wrong....
roborrr
am 19 Aug. 2023
0 Stimmen
7 Kommentare
You haven't been paying (close enough) attention... :)
You MUST <write a gateway function> to interface to and that calls your function. This function is called MEXFUNCTION and is the unresolved external in the link error message you received. You got that because you didn't write/include the needed gateway function of that name.
You then have a problem because your Fortran subroutine uses COMMON to obtain all its needed variables from the main program rather than passing them as arguments. You don't have any way to set/pass those in your code; they will all be undefined when try to call the function once there is a gateway function.
COMMON /DIM/ N1,N2,N3,N4,N5,N6,N7,N8,N9,N10,N11,N12,N13,N14,N15
COMMON /SOL/ NUMNP,NEQ,NWK,NWM,NWC,NUMEST,MIDEST,MAXEST,NSTE,MA
COMMON /EL/ IND,ICOUNT,NPAR(20),NUMEG,NEGL,NEGNL,IMASS,IDAMP,ISTAT
1 ,NDOF,KLIN,IEIG,IMASSN,IDAMPN
COMMON /VAR/ NG,KPRI,MODEX,KSTEP,ITE,ITEMAX,IREF,IEQREF,INOCMD
COMMON A(30000)
All of those will have to be defined and included with the named common in your routine. The modern Fortran way would be to make those module variables and USE the module.
The blank common array probably should just be made a local and passed to RUSS() which you also will have to compile and include the object file to be linked. (And, of course, calling RUSS() will undoubtedly start a cascade of all the subroutines/functions it calls and those which they call in turn. You've just begun to scratch the surface.
Then, for your mex function to be useful from MATLAB you would need to make any of those that can/need to be changed from one use to another arguments to your mex function; otherwise you would have to edit the fortran and recompile it every time anything at all changed; not a very useful function.
As said earlier, to think you can just compile and the code somehow be magically integrated with MATLAB is not the correct model of how the interface to external language(s) works.
Walter Roberson
am 19 Aug. 2023
Side note:
A fortran named COMMON block is exported to the rest of the world as a global variable that has the same name as the common block, and which is conceptually a union() of struct -- union because fortran named COMMON are not required to use the same number or type of variables, with the underlying memory being considered to be shared.
I do not recall at the moment the implementation of fortran unnamed COMMON blocks such as hte COMMON A(30000)
dpb
am 19 Aug. 2023
I don't recall otomh, either, vague recollections are that it is compiler dependent as to how/what they generate as the link symbol, but it's been too long since had to do an external linkage to a blank common block that I don't remember.
For @roborrr, it still may be a more expedient route to simply build the full executable and call it with system from MATLAB; it hasn't been explained just what the end objective is here and how MATLAB really fits into the picture to have a good answer.
But, it's going to be quite a lot of work to mex this, it would appear.
Walter Roberson
am 19 Aug. 2023
Looks like I had forgotten a lot about the details of common blocks... Oh well, not something I have had to use for rather some time now...
dpb
am 20 Aug. 2023
About the only thing fixed is the alignment of the origin; size, content, variable names, etc., etc., are all up to the user and don't have to be identical from one definition to another. Allows all kinds of "tricks" regarding data type and name punning, etc., ...
Walter Roberson
am 20 Aug. 2023
The document I was looking for said that size could differ for blank common but that the types needed to be the same for all versions; for named common it said the size and types had to be identical.
The restriction that named common blocks be the same size is so. Names can change positionally and type punning by EQUIVALENCE.
I'd guess it's pretty unlikely those are used in OP's code, but it's always possible and the safest (and simplest to try to mex this) route is to simply duplicate COMMON as is...the listing doesn't show an INCLUDE statement to bring in the COMMON; that could be original source doesn't use it or the posted came from listing that doesn't reflect preprocessing.
NOT using INCLUDE but having duplicate code in multiple program units is one of the most common ways to mess up and unintentionally change variables via common; a change in the block definition has to be faithfully duplicated everywhere in that case; it's all too easy to miss one or make a typo when are many to do.
A code I supported for years I've referred to often in the past deliberately uses the type punning in its database to, in various program units or for various purposes, refer to same memory locations as REAL or INTEGER variable types; I'd've never designed it that way, but the original authors did and it works very well; is just difficult to grasp initially. It, however, also uses C helper routines that move those data bytes by straight bit copying via memmove() when storing. Anyways, gotten way off track for OP's issues...
Kategorien
Mehr zu Virtual Vehicles finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!