I have written R code containing Rcpp function, which in turn calls other cpp functions through inline, on my Mac. I have switched to a Windows machine with a much more powerful cpu and higher RAM, but the same code takes on average twice as much to run on this new machine.
my R session info on Mac is here
and that of the Windows machine is here
As a clear example, this small function in my code (lik2altcpp.cpp)
#ifndef __lik2altcpp__
#define __lik2altcpp__
// [[Rcpp::depends(RcppArmadillo)]]
#include "RcppArmadillo.h"
#include "FactorialLog.cpp"
using namespace arma;
using namespace Rcpp;
// [[Rcpp::export]]
inline vec lik2altF(vec p,int k,double eps) {
wall_clock timer;
timer.tic();
double ptie=0,arg11=0,arg12=0,arg21=0,arg22=0,ptb=0,pu1=0,pu2=0;
double p1,p2,ps;
vec prob(2);
if (p(0)==0) p1=10e-20; else p1=p(0);
if (p(1)==0) p2=10e-20; else p2=p(1);
if (p(2)==0) ps=10e-20; else ps=p(2);
for (int i=0;i<=k;i++)
{
if (i!=0)
{
ptie=ptie+ exp(FactorialLog(2*k-i-1)-(FactorialLog(i-1)+FactorialLog(k-i)+FactorialLog(k-i))+i*log(ps)+(k-i)*log(p1)+(k-i)*log(p2));
}
if(i!=k)
{
arg11=arg11+exp(FactorialLog(k+i-1)-(FactorialLog(i)+FactorialLog(k-1))+k*log(p1)+i*log(p2)); //first argument of the P(1)
arg12=arg12+exp(FactorialLog(k+i-1)-(FactorialLog(i)+FactorialLog(k-1))+i*log(p1)+k*log(p2)); //first argument of the P(2)
}
if((i!=0) && (i!=k))
{
for(int j=0; j<=(k-i-1);j++)
{
arg21=arg21+ exp(FactorialLog(k+j-1)-(FactorialLog(i-1)+FactorialLog(k-i)+FactorialLog(j))+ i*log(ps)+(k-i)*log(p1)+j*log(p2)) + exp(FactorialLog(k+j-1)-(FactorialLog(i)+FactorialLog(k-i-1)+FactorialLog(j)) + i*log(ps)+(k-i)*log(p1)+j*log(p2)); //second argument of the P(1)
arg22=arg22+ exp(FactorialLog(k+j-1)-(FactorialLog(i-1)+FactorialLog(k-i)+FactorialLog(j))+ + i*log(ps)+j*log(p1)+(k-i)*log(p2)) + exp(FactorialLog(k+j-1)-(FactorialLog(i)+FactorialLog(k-i-1)+FactorialLog(j)) + i*log(ps)+j*log(p1)+(k-i)*log(p2)); //second argument of the P(2)
}
}
}
//summing up the terms of the prob. formula
pu1=arg11+arg21 ;
pu2=arg12+arg22;
// ptb=(p1+eps*ps)/(p1+p2+2*eps*ps); //the actual formula for ptb
///////////REVERT THE CHANGES AFTER THE TEST ////////////////
ptb=.5;
//Calculating probabilities
prob(0)=pu1+ptb*ptie;
prob(1)=pu2+(1-ptb)*ptie;
double n = timer.toc();
cout << "number of seconds: " << n;
return prob;
}
#endif //__lik2altcpp__
along with the function it includes(FactorialLog.cpp):
#ifndef __FactorialLog__
#define __FactorialLog__
#include "RcppArmadillo.h"
using namespace arma;
using namespace Rcpp;
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
inline double FactorialLog(int n)
{
if (n < 0)
{
std::stringstream os;
os << "Invalid input argument (" << n
<< "); may not be negative";
throw std::invalid_argument( os.str() );
}
else if (n > 254)
{
const double Pi = 3.141592653589793;
double x = n + 1;
return (x - 0.5)*log(x) - x + 0.5*log(2*Pi) + 1.0/(12.0*x);
}
else
{
double lf[] =
{
0.000000000000000,
0.000000000000000,
0.693147180559945,
1.791759469228055,
3.178053830347946,
4.787491742782046,
6.579251212010101,
8.525161361065415,
10.604602902745251,
12.801827480081469,
15.104412573075516,
17.502307845873887,
19.987214495661885,
22.552163853123421,
25.191221182738683,
27.899271383840894,
30.671860106080675,
33.505073450136891,
36.395445208033053,
39.339884187199495,
42.335616460753485,
45.380138898476908,
48.471181351835227,
51.606675567764377,
54.784729398112319,
58.003605222980518,
61.261701761002001,
64.557538627006323,
67.889743137181526,
71.257038967168000,
74.658236348830158,
78.092223553315307,
81.557959456115029,
85.054467017581516,
88.580827542197682,
92.136175603687079,
95.719694542143202,
99.330612454787428,
102.968198614513810,
106.631760260643450,
110.320639714757390,
114.034211781461690,
117.771881399745060,
121.533081515438640,
125.317271149356880,
129.123933639127240,
132.952575035616290,
136.802722637326350,
140.673923648234250,
144.565743946344900,
148.477766951773020,
152.409592584497350,
156.360836303078800,
160.331128216630930,
164.320112263195170,
168.327445448427650,
172.352797139162820,
176.395848406997370,
180.456291417543780,
184.533828861449510,
188.628173423671600,
192.739047287844900,
196.866181672889980,
201.009316399281570,
205.168199482641200,
209.342586752536820,
213.532241494563270,
217.736934113954250,
221.956441819130360,
226.190548323727570,
230.439043565776930,
234.701723442818260,
238.978389561834350,
243.268849002982730,
247.572914096186910,
251.890402209723190,
256.221135550009480,
260.564940971863220,
264.921649798552780,
269.291097651019810,
273.673124285693690,
278.067573440366120,
282.474292687630400,
286.893133295426990,
291.323950094270290,
295.766601350760600,
300.220948647014100,
304.686856765668720,
309.164193580146900,
313.652829949878990,
318.152639620209300,
322.663499126726210,
327.185287703775200,
331.717887196928470,
336.261181979198450,
340.815058870798960,
345.379407062266860,
349.954118040770250,
354.539085519440790,
359.134205369575340,
363.739375555563470,
368.354496072404690,
372.979468885689020,
377.614197873918670,
382.258588773060010,
386.912549123217560,
391.575988217329610,
396.248817051791490,
400.930948278915760,
405.622296161144900,
410.322776526937280,
415.032306728249580,
419.750805599544780,
424.478193418257090,
429.214391866651570,
433.959323995014870,
438.712914186121170,
443.475088120918940,
448.245772745384610,
453.024896238496130,
457.812387981278110,
462.608178526874890,
467.412199571608080,
472.224383926980520,
477.044665492585580,
481.872979229887900,
486.709261136839360,
491.553448223298010,
496.405478487217580,
501.265290891579240,
506.132825342034830,
511.008022665236070,
515.890824587822520,
520.781173716044240,
525.679013515995050,
530.584288294433580,
535.496943180169520,
540.416924105997740,
545.344177791154950,
550.278651724285620,
555.220294146894960,
560.169054037273100,
565.124881094874350,
570.087725725134190,
575.057539024710200,
580.034272767130800,
585.017879388839220,
590.008311975617860,
595.005524249382010,
600.009470555327430,
605.020105849423770,
610.037385686238740,
615.061266207084940,
620.091704128477430,
625.128656730891070,
630.172081847810200,
635.221937855059760,
640.278183660408100,
645.340778693435030,
650.409682895655240,
655.484856710889060,
660.566261075873510,
665.653857411105950,
670.747607611912710,
675.847474039736880,
680.953419513637530,
686.065407301994010,
691.183401114410800,
696.307365093814040,
701.437263808737160,
706.573062245787470,
711.714725802289990,
716.862220279103440,
722.015511873601330,
727.174567172815840,
732.339353146739310,
737.509837141777440,
742.685986874351220,
747.867770424643370,
753.055156230484160,
758.248113081374300,
763.446610112640200,
768.650616799717000,
773.860102952558460,
779.075038710167410,
784.295394535245690,
789.521141208958970,
794.752249825813460,
799.988691788643450,
805.230438803703120,
810.477462875863580,
815.729736303910160,
820.987231675937890,
826.249921864842800,
831.517780023906310,
836.790779582469900,
842.068894241700490,
847.352097970438420,
852.640365001133090,
857.933669825857460,
863.231987192405430,
868.535292100464630,
873.843559797865740,
879.156765776907600,
884.474885770751830,
889.797895749890240,
895.125771918679900,
900.458490711945270,
905.796028791646340,
911.138363043611210,
916.485470574328820,
921.837328707804890,
927.193914982476710,
932.555207148186240,
937.921183163208070,
943.291821191335660,
948.667099599019820,
954.046996952560450,
959.431492015349480,
964.820563745165940,
970.214191291518320,
975.612353993036210,
981.015031374908400,
986.422203146368590,
991.833849198223450,
997.249949600427840,
1002.670484599700300,
1008.095434617181700,
1013.524780246136200,
1018.958502249690200,
1024.396581558613400,
1029.838999269135500,
1035.285736640801600,
1040.736775094367400,
1046.192096209724900,
1051.651681723869200,
1057.115513528895000,
1062.583573670030100,
1068.055844343701400,
1073.532307895632800,
1079.012946818975000,
1084.497743752465600,
1089.986681478622400,
1095.479742921962700,
1100.976911147256000,
1106.478169357800900,
1111.983500893733000,
1117.492889230361000,
1123.006317976526100,
1128.523770872990800,
1134.045231790853000,
1139.570684729984800,
1145.100113817496100,
1150.633503306223700,
1156.170837573242400,
};
return lf[n];
}
}
#endif //__FactorialLog__
runs three times as fast on Mac as it does on Windows. You can try it e.g. with these inputs:
> lik2altF(p=c(.3,.3,.4),k=10000,eps=1000)
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
I have read the model answer on unresolved externals and found it to be incredibly useful and have got it down to just these last two stubborn errors which are beyond me.
I've attached all the code just in case, if you would like to see the headers or anything else please say.
// Stokes theory calculations
#include <math.h>
#include <stdio.h>
#include <process.h>
#include <string.h>
#include <conio.h>
#include <stdlib.h>
#define ANSI
#include "../Allocation.h"
#define Main
#define Char char
#define Int int
#define Double double
#include "../Allocation.h"
#include "../Headers.h"
Double
kH, skd, ckd, tkd, SU;
Double
ss[6], t[6], C[6], D[6], E[6], e[6];
// Main program
int main(void)
{
int i, Read_data(void), iter, Iter_limit = 40;
double F(double), kd1, kd2, kFM, omega, delta, accuracy = 1.e-6, F1, F2, Fd;
void CDE(double), AB(void), Output(void);
Input1 = fopen("../Data.dat", "r");
strcpy(Convergence_file, "../Convergence.dat");
strcpy(Points_file, "../Points.dat");
monitor = stdout;
strcpy(Theory, "Stokes");
strcpy(Diagname, "../Catalogue.res");
Read_data();
z = dvector(0, 2 * n + 10);
Y = dvector(0, n);
B = dvector(0, n);
coeff = dvector(0, n);
Tanh = dvector(0, n);
monitor = stdout;
H = MaxH;
iff(Case, Wavelength)
{
kd = 2. * pi / L;
kH = kd * H;
CDE(kd);
}
// If period is specified, solve dispersion relation using secant method
// Until February 2015 the bisection method was used for this.
// I found that in an extreme case (large current) the bracketting
// of the solution was not correct, and the program failed,
// without printing out a proper error message.
iff(Case, Period)
{
fprintf(monitor, "\n# Period has been specified.\n# Now solving for L/d iteratively, printing to check convergence\n\n");
omega = 2 * pi / T;
// Fenton & McKee for initial estimate
kFM = omega*omega*pow(1 / tanh(pow(omega, 1.5)), (2. / 3.));
kd1 = kFM;
kd2 = kFM*1.01;
CDE(kd2);
F2 = F(kd2);
for (iter = 1; iter <= Iter_limit; ++iter)
{
CDE(kd1);
F1 = F(kd1);
Fd = (F2 - F1) / (kd2 - kd1);
delta = F1 / Fd;
kd2 = kd1;
kd1 = kd1 - delta;
fprintf(monitor, "%8.4f\n", 2 * pi / kd1);
if (fabs(delta / kd1) < accuracy) break;
F2 = F1;
if (iter >= Iter_limit)
{
printf("\n\nSecant for solution of wavenumber has not converged");
printf("\nContact John Fenton johndfenton#gmail.com");
getch();
exit(1);
}
}
kd = kd1;
kH = kd * H;
}
z[1] = kd;
z[2] = kH;
SU = 0.5*kH / pow(kd, 3);
printf("\n# Stokes-Ursell no.: %7.3f", SU);
if (SU > 0.5)
printf(" > 1/2. Results are unreliable");
else
printf(" < 1/2, Stokes theory should be valid");
e[1] = 0.5 * kH;
for (i = 2; i <= n; i++) e[i] = e[i - 1] * e[1];
// Calculate coefficients
AB();
z[7] = C[0] + e[2] * C[2] + e[4] * C[4]; // ubar
z[8] = -e[2] * D[2] - e[4] * D[4];
z[9] = 0.5 * C[0] * C[0] + e[2] * E[2] + e[4] * E[4];
if (Current_criterion == 1)
{
z[5] = Current*sqrt(kd);
z[4] = z[7] + z[5];
z[6] = z[4] + z[8] / kd - z[7];
}
if (Current_criterion == 2)
{
z[6] = Current*sqrt(kd);
z[4] = z[6] - z[8] / kd + z[7];
z[5] = z[4] - z[7];
}
iff(Case, Wavelength) z[3] = 2 * pi / z[4];
iff(Case, Period) z[3] = T * sqrt(kd);
for (i = 1; i <= n; i++)
Tanh[i] = tanh(i*z[1]);
// Output results and picture of wave
Solution = fopen("Solution.res", "w");
Elevation = fopen("Surface.res", "w");
Flowfield = fopen("Flowfield.res", "w");
Output();
fflush(NULL);
printf("\nTouch key to continue "); getch();
printf("\n\nFinished\n");
}
I get these error messages:
LNK2019 unresolved external symbol "void __cdecl Output(void)" (?Output##YAXXZ) referenced in function _main Stokes
LNK2019 unresolved external symbol "double * __cdecl dvector(long,long)" (?dvector##YAPANJJ#Z) referenced in function _main Stokes
I have checked everything on the list given to try and find where these errors are coming from and have whittled it down to just these two left.
Things tried so far:
Checking basic syntax
Checking and ensuring correct headers are available
Looked at external dependencies (but i don't really know what i'm doing here)
Looked at the solutions tried here but none worked.
Any help would be greatly appreciated!
Unresolved External Symbols means that your code can't find the definition of the method or class you're trying to use. This usually means one (or more) of several things has happened:
You didn't point to the directory that contains the object library (.lib on Windows, .so on Linux) for the library you're using
You forgot to specify in the linker that you need to use the library in question (that list of kernel32.lib, user32.lib,... needs to include the name of the library you're using)
The library you're trying to use is meant to be linked statically and you're trying to link it dynamically (or vise-versa). Check the documentation for the library and make sure you're using the correct form. Some libraries expect extra #define statements to be included or omitted depending on whether you're linking statically or dynamically.
You changed build options and forgot to update the libraries in the other build options. If you're set to Release or x64, check to make sure that your build options are set correctly in all environments.
EDIT: I'll also corroborate what the others said in the original comment thread: make sure that the code that defines Output() and dvector() are being linked to by your code.
There's a few other options, but those are the big ones that happen most frequently.