I am using armadillo and R through RcppArmadillo.
I have a sparse matrix and a row number as input. I would like to search the corresponding row of the matrix and return the location of the nonzeros.
So far my function looks like
// [[Rcpp::export]]
arma::uvec findAdjacentStates(arma::sp_mat adjacency, int row) {
arma::uvec out(adjacency.n_cols);
arma::SpSubview<double>::const_iterator start = adjacency.row(row).begin();
arma::SpSubview<double>::const_iterator end = adjacency.row(row).end();
for(arma::SpSubview<double>::const_iterator it = start; it != end; ++it)
{
Rcout << "location: " << it.row() << "," << it.col() << " ";
Rcout << "value: " << (*it) << std::endl;
}
return out;
}
which is based on a previous SO answer.
The function crashes R.
require(Matrix)
x = rsparsematrix(10, 10, .2)
x = x > 1
x = as(x, "dgCMatrix")
findAdjacentStates(x, 1)
One thing that is not clear to me is how to iterate on a row vector specifically; the previous SO answer was for iterating on a sparse matrix.
Update: according to valgrind the problem is in operator++ (SpSubview_iterators_meat.hpp:319), so it seems this is not the correct way to iterate on a sparse row vector
The way to iterate on a sparse matrix row is with a sp_mat::row_iterator. Unfortunately, there's no way to know ahead of time what size your output vector would be and uvec objects don't have a push_back like regular vectors do. Here would be my suggestion:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;
// [[Rcpp::export]]
IntegerVector findAdjacentStates(sp_mat adjacency, int row) {
IntegerVector out;
sp_mat::const_row_iterator start = adjacency.begin_row(row);
sp_mat::const_row_iterator end = adjacency.end_row(row);
for ( sp_mat::const_row_iterator i = start; i != end; ++i )
{
out.push_back(i.col());
}
return out;
}
Which we can test out easily enough:
# We need Rcpp and Matrix:
library(Rcpp)
library(Matrix)
# This is the C++ script I wrote:
sourceCpp('SOans.cpp')
# Make example data (setting seed for reproducibility):
set.seed(123)
x = rsparsematrix(10, 10, .2)
# And test the function:
findAdjacentStates(x, 1)
[1] 4
x
10 x 10 sparse Matrix of class "dgCMatrix"
[1,] . . 0.84 . 0.40 0.7 . . . -0.56
[2,] . . . . -0.47 . . . . .
[3,] . . . . . . . . -2.00 .
[4,] 0.15 . . . . . . . . -0.73
[5,] 1.80 . . . . . . . . .
[6,] . . . . . . . . 0.11 .
[7,] . . -1.10 . . . . -1.70 -1.10 .
[8,] . . . . . . . 1.30 . -0.22
[9,] -0.63 . 1.20 . . . . 0.36 . .
[10,] . . . . 0.50 -1.0 . . . .
So, we can see this works; row 1 (in C++ terms; row 2 in R terms) has only one non-zero element, which is in column 4 (in C++ terms; column 5 in R terms). This should work if you're wanting to return the output to R. If you're wanting to use the output in another C++ function, depending on what you're doing you may prefer to have a uvec rather than an IntegerVector, but you can just convert the IntegerVector to a uvec (probably not the most efficient solution, but the best I thought of right now):
// [[Rcpp::export]]
uvec findAdjacentStates(sp_mat adjacency, int row) {
IntegerVector tmp;
sp_mat::const_row_iterator start = adjacency.begin_row(row);
sp_mat::const_row_iterator end = adjacency.end_row(row);
for ( sp_mat::const_row_iterator i = start; i != end; ++i )
{
tmp.push_back(i.col());
}
uvec out = as<uvec>(tmp);
return out;
}
I'm creating a command line game that includes a 10 x 10 char array, represented like this:
0 1 2 3 4 5 6 7 8 9
0 . . . . . . . . . .
1 . . . . . . . . . .
2 . . . . . . . . . .
3 . . . . . . . b . .
4 . . A B C . 1 2 3 .
5 . . . . . . . . . .
6 . . . . . . . . . .
7 . . . . . C c 3 . .
8 . . . . . . . . . .
9 . . . . . . . . . .
Each . represents an unoccupied spot on the board and the letters and numbers are pieces that have already been played. The numbers on the upper edge and left edge are just for reference.
In order to calculate points and ensure that pieces are played in the correct places, I'd like to create "sub-array" of consecutive pieces adjacent to the piece that has just been played. From the example above, if B had just been played, then that char array would contain A, B, and C.
I'm having a hard time finding the "starting" (left-most) and "ending" (right-most) pieces of this consecutive sub-array. Once I have those this is easy to solve. Obviously I could start at one end of the board and just add to an array any piece that's not ., but then I'd end up with all the pieces in that row, not just the ones adjacent to the piece that has just been played.
I've tried the following, but it still prints the wrong output (off by one on both sides):
void Board::createHorizontalRun(int row, int column) {
int i = column;
int j = column;
while (array[row][i] != '.' && i >= 0 && i <= 9) {
i--;
}
while (array[row][j] != '.' && j >= 0 && j <= 9) {
j++;
}
cout << "run begins at " << i << endl;
cout << "run ends at " << j << endl;
}
How can I find the starting and ending locations of the consecutive pieces adjacent to the piece that has just been played?
Here's what I came up with after following Sam's advice:
vector<char> Board::getHorizontalRun(int row, int column) {
int runStart = column;
int runEnd = column;
vector<char> horizontalRun;
// find starting position of run
while (true) {
if (isInBounds(row, runStart - 1)) {
if (array[row][runStart - 1] == '.') {
break;
} else {
runStart--;
}
} else {
break;
}
}
// find ending position of array
while (true) {
if (isInBounds(row, runEnd + 1)) {
if (array[row][runEnd + 1] == '.') {
break;
} else {
runEnd++;
}
} else {
break;
}
}
// Use start and end positions to populate vector
for (int i = runStart; i <= runEnd; i++) {
horizontalRun.push_back(array[row][i]);
}
return horizontalRun;
}
I need a Stata code similar to this SAS code:
i=1;
do while (i <= 6);
A=B(C(i));
i=i+1;
end;
Both B and C are arrays as
B_1, B_2, B_3, B_4, B_5 and B_6
C_1, C_2, C_3, C_4, C_5 and C_6
For example, if i = 1, then C(i) = C_1.
For row 3, if C_1 = 5, then I want to set A to B_5.
my problem is with accessing the array entry B(C(i)). How can I write this access in Stata?
There isn't a one-to-one equivalent. See
FAQ . . . . . . . . . . . . . . . . Implementing SAS-like ARRAYs in Stata
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . W. Gould
2/03 How do I implement SAS-like ARRAYs in Stata?
Here is a link.
This is a little clumsy, but (insofar as I understand the question) it does what you are asking for:
clear all
forvalues i = 1/6 {
scalar c_`i' = 7-`i'
}
forvalues i = 1/6 {
scalar b_`i' = ceil(100/`i')
}
// test method
forvalues i = 1/6 {
scalar a = b_`=c_`i''
di a
}
scalar list
Note that as you've written the question, a is overwritten each time, so presumably there are commands following "a = b(c(i))". The Stata syntax '=...' (with a proper opening single quote) evaluates the scalar c_'i' and inserts the resulting value in the name for b_?, which a is then set equal to.
I have just started to learn PSSE model writing. As a starting point, I tried to compile PSSE example givem in Programe Operation Manuel page 21-16 and got the following errors. I use the Env. Manager and it seems that all paths and libs for Microsoft visual studio 2010 and Intel visual fortran 15.0 are set properly. I also set the PATH to PSSBIN folder and LIB to PSSLIB. Can anyone please suggest me where I'm going wrong?
The model code:
SUBROUTINE DEMOEX(I,ISLOT)
C
INCLUDE 'COMON4.INS'
C
INTEGER I,ISLOT
C
C I = MACHINE ARRAY INDEX
C ISLOT = ARRAY ALLOCATION TABLE INDEX
C J = STRTIN(1,ISLOT) [ USES CON(J) THROUGH CON(J+2) ]
C K = STRTIN(2,ISLOT) [ USES STATE(K) AND STATE(K+1) ]
C
INTRINSIC MAX, ABS
EXTERNAL BADMID, DOCUHD
C
INTEGER IB, J, K, IBUS, JJ
REAL VERROR
LOGICAL NEW
CHARACTER IM*2
C
IF (MODE.EQ.8)
. CON_DSCRPT(1)='Tr'
. CON_DSCRPT(2)='K'
. CON_DSCRPT(3)='Te'
. RETURN
...FIN
C
C GET STARTING 'CON' AND 'STATE' INDICES
C
J=STRTIN(1,ISLOT)
K=STRTIN(2,ISLOT)
C
IF (MODE .GT. 4) GO TO 1000
C
C BUS SEQUENCE NUMBER NEGATIVE IF MACHINE
C IS OFF-LINE, SVS OR INDUCTION MACHINE
C
IB=NUMTRM(I)
IF (IB.LE.0) RETURN
C
IF (MIDTRM) GO TO 900
GO TO (100,200,300,400), MODE
C
C MODE = 1 - INITIALIZE
C
100 STATE(K)=ECOMP(I)
STATE(K+1)=EFD(I)
VREF(I)=ECOMP(I) + EFD(I)/CON(J+1)
IF (EFD(I).LT.0.) WRITE(LPDEV,307) NUMBUS(IB),MACHID(I)
RETURN
C
C MODE = 2 - CALCULATE DERIVATIVES
C
200 DSTATE(K)=(ECOMP(I)-STATE(K))/CON(J)
VERROR=VREF(I)+VOTHSG(I)-STATE(K)
DSTATE(K+1)=(CON(J+1)*VERROR-STATE(K+1))/CON(J+2)
RETURN
C
C MODE = 3 - SET EFD
C
300 EFD(I)=MAX(STATE(K+1),0.)
RETURN
C
C MODE = 4 - SET NINTEG
C
400 NINTEG=MAX(NINTEG,K+1)
RETURN
C
C MODE > 4
C
1000 IM=MACHID(I)
IB=ABS(NUMTRM(I))
IBUS=NUMBUS(IB)
C
IF (MODE.EQ.6) GO TO 2000
C
TO PRINT-HEADING
C .
. UNLESS (NEW)
. . NEW=.TRUE.
. . CALL DOCUHD(*1900)
. . WRITE(IPRT,97) IBUS,IM
. ...FIN
C .
...FIN
END
2000 END
The error messages:
ifort /nologo /assume:buffered_io /traceback /libs:dll /threads /c /Qip /extend_source:132 /noaltparam
/fpscomp:logicals /Qprec /warn:nodeclarations /warn:unused /warn:truncated_source /Qauto /fp:source /iface:cvf
/define:DLLI /include:"C:\Program Files (x86)\PTI\PSSE33\PSSLIB" /object:"D:\IVF15test\DEMOEX.obj"
/module:"D:\IVF15test" "D:\IVF15test\DEMOEX.f"
D:\IVF15test\DEMOEX.f(10): error #5082: Syntax error, found END-OF-STATEMENT when expecting one of: BLOCK
PROGRAM BLOCKDATA MODULE INTEGER REAL COMPLEX TYPE BYTE CHARACTER CLASS ...
IF (MODE.EQ.8)
------------------------^
D:\IVF15test\DEMOEX.f(11): error #5082: Syntax error, found '.' when expecting one of: <LABEL>
<END-OF-STATEMENT> ; BLOCK PROGRAM BLOCKDATA MODULE INTEGER REAL COMPLEX ...
. CON_DSCRPT(1)='Tr'
----------^
D:\IVF15test\DEMOEX.f(12): error #5082: Syntax error, found '.' when expecting one of: <LABEL>
<END-OF-STATEMENT> ; BLOCK PROGRAM BLOCKDATA MODULE INTEGER REAL COMPLEX ...
. CON_DSCRPT(2)='K'
----------^
D:\IVF15test\DEMOEX.f(13): error #5082: Syntax error, found '.' when expecting one of: <LABEL>
<END-OF-STATEMENT> ; BLOCK PROGRAM BLOCKDATA MODULE INTEGER REAL COMPLEX ...
. CON_DSCRPT(3)='Te'
----------^
D:\IVF15test\DEMOEX.f(14): error #5082: Syntax error, found '.' when expecting one of: <LABEL>
<END-OF-STATEMENT> ; BLOCK PROGRAM BLOCKDATA MODULE INTEGER REAL COMPLEX ...
. RETURN
----------^
D:\IVF15test\DEMOEX.f(15): error #5082: Syntax error, found '.' when expecting one of: <LABEL>
<END-OF-STATEMENT> ; BLOCK PROGRAM BLOCKDATA MODULE INTEGER REAL COMPLEX ...
...FIN
----------^
D:\IVF15test\DEMOEX.f(18): error #5149: Illegal character in statement label field [I]
IF (MODE .GT. 4) GO TO 1000
^
D:\IVF15test\DEMOEX.f(18): error #5149: Illegal character in statement label field [F]
IF (MODE .GT. 4) GO TO 1000
-^
D:\IVF15test\DEMOEX.f(18): error #5149: Illegal character in statement label field [(]
IF (MODE .GT. 4) GO TO 1000
---^
D:\IVF15test\DEMOEX.f(18): error #5149: Illegal character in statement label field [M]
IF (MODE .GT. 4) GO TO 1000
----^
D:\IVF15test\DEMOEX.f(18): error #5276: Unbalanced parentheses
IF (MODE .GT. 4) GO TO 1000
---------------^
D:\IVF15test\DEMOEX.f(15): catastrophic error: Could not recover from previous syntax error
compilation aborted for D:\IVF15test\DEMOEX.f (code 1)
it's better to write code using fortran... but, you didn't finished flex code from pom.pdf section 21.9... I finished code in flex language, and you can compile that now without errors, but with warnings (some declared variables code didn't use etc.), I'm not sure that it will be work correct in psse environment...
C
C[UEXC] 05/23/02 EXAMPLE USER EXCITATION SYSTEM MODEL
C
C * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
C * *
C * THIS PROGRAM AND ITS DOCUMENTATION ARE TRADE SECRETS OF POWER TECHNO- *
C * LOGIES, A DIVISION OF S&W CONSULTANTS, INC. THEY HAVE BEEN LEASED TO *
C * YOU, OUR CLIENT, *
C * SUBJECT TO TERMS WHICH PROHIBIT YOU FROM DISCLOSING OR TRANSFERRING *
C * THE PROGRAM OR ITS DOCUMENTATION, WHETHER IN ITS ORIGINAL OR MODIFIED *
C * FORM, TO A THIRD PARTY, OR FROM USING THE PROGRAM FOR ANY PURPOSE *
C * OTHER THAN COMPUTATION RELATING TO YOUR OWN SYSTEM. ANY SUCH *
C * TRANSFER OR USE BY YOU OR YOUR EMPLOYEES WILL CONSTITUTE A BREACH OF *
C * CONFIDENCE AND OF THE CONTRACT UNDER WHICH RIGHTS OF USE HAVE BEEN *
C * GRANTED. *
C * *
C * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
C
SUBROUTINE UEXC(IARG,ISLOT)
C
C THIS IS A SIMPLIFIED EXAMPLE EXCITATION SYSTEM MODEL
C
C SUBROUTINE UEXC
C IARG = MACHINE ARRAY INDEX
C ISLOT = ARRAY ALLOCATION TABLE INDEX
C J = STRTIN(1,ISLOT) [ USES CON(J) THROUGH CON(J+8) ]
C K = STRTIN(2,ISLOT) [ USES STATE(K) AND STATE(K+3) ]
C
C USE DYNAMICS, ONLY: NUMTRM, STRTIN,
C * EFD,
C * ECOMP, VOTHSG, VREF,
C * VUEL, VOEL,
C * CON, VAR,
C * STORMT, STATE, DSTATE, STORE
C USE PSSCM4, ONLY: NUMBUS, BASVLT,
C * BUSNAM,
C * MACHID
C
C$INCLUDE PERM4.INS
C$INCLUDE DSCOM4.INS
$INSERT COMON4.INS
C
INTEGER IARG, ISLOT
C
C INTRINSIC MAX
EXTERNAL BADMID
C
INTEGER I, J, K, JJ, KK,
* IB, IBUS, IBPTR
REAL VERROR, VR, DEL2, FDBK, SS, R_TF_KF
LOGICAL HIGH, LOW, NEW
CHARACTER CB1*6, CB2*6
CHARACTER IM*2, VLTI*4
C
IF (MODE.EQ.8) GO TO 1500 ! GET DATA DESCRIPTIONS
I=IARG ! MACHINE ARRAY INDEX
J=STRTIN(1,ISLOT) ! STARTING 'CON'
K=STRTIN(2,ISLOT) ! STARTING 'STATE'
C
IF (MODE.GT.4) GO TO 1000
C
IB=NUMTRM(I) ! RETURN IF OFF-LINE
IF (IB.LE.0) RETURN ! OR SVS OR INDUCTION MACHINE
$1
C
C MODEL NOT IMPLEMENTED FOR MSTR/MRUN
C
IF (MIDTRM)
. CALL BADMID(I,IB,'UEXC')
. RETURN
...FIN
C
C MODE 2 - CALCULATE DERIVATIVES
IF (MODE.EQ.2) ! CALCULATE DERIVATIVES
C .
. WHEN (MIDTRM) ! MODE 2 Z-FORM
C . the midterm simulation mode is not implemented
C . .
C . .
. ...FIN
$1
. ELSE ! STATE SPACE
C . MODE 2 code portion is inserted here
C .
. . HIGH=STATE(K+1).GE.CON(J+3)
C .
. . WHEN (HIGH)
. . . STATE(K+1)=CON(J+3)
. . . STORE(K+1)=CON(J+3)
. . ...FIN
. . ELSE
. . . LOW=STATE(K+1).LE.CON(J+4)
C . . .
. . . IF (LOW)
. . . . STATE(K+1)=CON(J+4)
. . . . STORE(K+1)=CON(J+4)
. . . ...FIN
C . . .
. . ...FIN
C . .
C . . HANDLING SMALL TIME CONSTANTS
. . DEL2=2.*DELT
C . .
. . WHEN (CON(J).LE.DEL2)
. . . STORE(K)=ECOMP(I)
. . . STATE(K)=ECOMP(I)
. . ...FIN
. . ELSE DSTATE(K)=(ECOMP(I)-STATE(K))/CON(J)
C . .
. . DSTATE(K+2)=(STATE(K+1)/CON(J+5)-STATE(K+2))*CON(J+5)/CON(J+6)
C . .
. . FDBK=STATE(K+2)*CON(J+7)/CON(J+8)-STATE(K+3) ! FEEDBACK BLOCK OUTPUT
. . DSTATE(K+3)=FDBK/CON(J+8)
C . .
C . . TEMPORARY VARIABLE SS
. . SS=(VREF(I)+VOTHSG(I)-STATE(K)-FDBK)*CON(J+1)
C . .
. . WHEN (CON(J+2).LE.DEL2)
. . . STORE(K+1)=SS
. . . STATE(K+1)=SS
. . ...FIN
. . ELSE
. . . DSTATE(K+1)=(SS-STATE(K+1))/CON(J+2)
C . . .
. . . CONDITIONAL
. . . . (HIGH) IF (DSTATE(K+1).GT.0.) DSTATE(K+1)=0.
. . . . (LOW) IF (DSTATE(K+1).LT.0.) DSTATE(K+1)=0.
. . . ...FIN
C . . .
. . ...FIN
C . .
. ...FIN
C .
. RETURN
...FIN
$1
C MODE 3 - SET EFD
IF (MODE.EQ.3)
C .
. WHEN (MIDTRM) ! RESET STORES FOR CHANGE
C . the midterm simulation mode is not implemented
C . . ! IN DELT (MIDTERM)
C . .
. ...FIN
. ELSE EFD(I)=STATE(K+2) ! STATE SPACE
C . MODE 3 code portion is inserted here
C .
. RETURN
...FIN
$1
C MODE 1 - INITIALIZATION
IF (MODE.EQ.1) ! INITIALIZE
. WHEN (MIDTRM)
C . the midterm simulation mode is not implemented
C . .
C . .
. ...FIN
. ELSE
C . MODE 1 code portion is inserted here
C . . TEMPORARY VARIABLE SS
. . SS=CON(J+5)*EFD(I)
. . VREF(I)=ECOMP(I)+SS/CON(J+1)
C . .
. . IF (SS.GE.CON(J+3) .OR. SS.LE.CON(J+4))
. . . WRITE(LPDEV,307) NUMBUS(IB),MACHID(I)
. . ...FIN
C . .
. . STATE(K)=ECOMP(I)
. . STATE(K+1)=SS
. . STATE(K+2)=EFD(I)
. . STATE(K+3)=EFD(I)*CON(J+7)/CON(J+8)
. ...FIN
C .
. RETURN
...FIN
C
C MODE 4 -SET NINTEG
C MODE 4 code portion is inserted here
IF (K+3.GT.NINTEG) NINTEG=K+3
RETURN
$1
C MODE > 4
C
1000 IM=MACHID(I)
IB=ABS(NUMTRM(I))
IBUS=NUMBUS(IB)
C
IF (MODE.EQ.6) GO TO 2000
C
C MODE 5 OR 7 - ACTIVITY DOCU
C
IF (MODE.EQ.5)
. CALL DOCUHD(*1900)
. GO TO 1100
...FIN
C
$1
C DATA CHECKING CODE
C
C code portion # 1 for DOCU checking mode is inserted here
NEW=.FALSE.
DEL2=2.*DELT
C
UNLESS (CON(J).GT.0. .AND. CON(J).LE.5.0) ! TR
. PRINT-HEADING
. WRITE(IPRT,107) CON(J)
...FIN
C
UNLESS (CON(J+1).GE.10. .AND. CON(J+1).LE.500.0) ! KA
. PRINT-HEADING
. WRITE(IPRT,108) CON(J+1)
...FIN
C
UNLESS (CON(J+2).GT.0. .AND. CON(J+2).LE.1.0) ! TA
. PRINT-HEADING
. WRITE(IPRT,109) CON(J+2)
...FIN
C
UNLESS (CON(J+3).GE.0.5 .AND. CON(J+3).LE.10.0) ! VRMAX
. PRINT-HEADING
. WRITE(IPRT,110) CON(J+3)
...FIN
C
UNLESS (CON(J+4).GE.-10.0 .AND. CON(J+4).LE.0.) ! VRMIN
. PRINT-HEADING
. WRITE(IPRT,111) CON(J+4)
...FIN
C
UNLESS (CON(J+5).GE.-1.0 .AND. CON(J+5).LE.1.0) ! KE
. PRINT-HEADING
. WRITE(IPRT,112) CON(J+5)
...FIN
C
UNLESS (CON(J+6).GT.DEL2 .AND. CON(J+6).LE.1.0) ! TE
. PRINT-HEADING
. WRITE(IPRT,113) CON(J+6)
...FIN
C
UNLESS (CON(J+7).GE.0. .AND. CON(J+7).LE.0.3) ! KF
. PRINT-HEADING
. WRITE(IPRT,114) CON(J+7)
...FIN
C
UNLESS (CON(J+8).GT.DEL2 .AND. CON(J+8).LE.1.5) ! TF
. PRINT-HEADING
. WRITE(IPRT,115) CON(J+8)
...FIN
C
R_TF_KF=CON(J+8)/CON(J+7)
UNLESS (R_TF_KF.GE.5.0 .AND. R_TF_KF.LE.15.0) ! RATIO TF/KF
. PRINT-HEADING
. WRITE(IPRT,116) R_TF_KF
...FIN
C
C (DATA CHECKING PERFORMED FOR ALL CONS)
C
UNLESS (NEW) RETURN
C
C DATA TABULATION CODE
C
1100 JJ=J+8
KK=K+3
C
CALL VLTFOR(VLTI,BASVLT(IB))
IBPTR = 0
CALL ADINTN (JJ,CB1,IBPTR)
IBPTR = 0
CALL ADINTN (KK,CB2,IBPTR)
WRITE(IPRT,17) IBUS,BUSNAM(IB),VLTI,IM,J,CB1,K,CB2
WRITE(IPRT,27) (CON(K),K=J,JJ)
C
1900 RETURN
C
C MODE 6 - ACTIVITY DYDA
C
2000 WRITE(IPRT,507) IBUS,IM,(CON(K),K=J,J+8)
RETURN
$1
C MODE 8 - ASSIGN DESCRIPTIONS FOR DATA EDITOR
C
C MODE 8 code portion is inserted here
1500 CON_DSCRPT(1) ='TR'
CON_DSCRPT(2) ='KA'
CON_DSCRPT(3) ='TA'
CON_DSCRPT(4) ='VRMAX'
CON_DSCRPT(5) ='VRMIN'
CON_DSCRPT(6) ='KE'
CON_DSCRPT(7) ='TE'
CON_DSCRPT(8) ='KF'
CON_DSCRPT(9) ='TF'
RETURN
$1
C
C a code portion for DOCU report is inserted here
17 FORMAT(//6X,'** UEXC',' ** BUS NAME BSKV MACH',
* ' C O N S S T A T E S'/,
* I23,1X,A8,1X,A4,2X,A2,1X,2(I7,'-',A6))
27 FORMAT(/5X,'TR KA TA VRMAX VRMIN KE TE',
* ' KF TF'/
* 3X,F5.3,F8.2,2F7.3,2F8.3,3F7.3)
97 FORMAT(//' BUS',I7,' MACHINE ',A,':')
C
C code portion # 2 for DOCU checking mode (messages) is inserted here
C DOCU CHECKING MESSAGES
107 FORMAT(' TR=',F15.4)
108 FORMAT(' KA=',F15.4)
109 FORMAT(' TA=',F15.4)
110 FORMAT(' VRMAX=',F15.4)
111 FORMAT(' VRMIN=',F15.4)
112 FORMAT(' KE=',F15.4)
113 FORMAT(' TE=',F15.4)
114 FORMAT(' KF=',F15.4)
115 FORMAT(' TF=',F15.4)
116 FORMAT(' RATIO TF/KF=',F15.4)
C
307 FORMAT(' UEXC AT BUS',I7,' MACHINE ',A,
* ' INITIALIZED OUT OF LIMITS')
C a code portion for DYDA record is inserted here
507 FORMAT(I6,' ''USRMDL''',2X,A2,' ''UEXC''',1X,4G13.5,/7X,5G13.5,'/')
$1
TO PRINT-HEADING
C .
. UNLESS (NEW)
. . NEW=.TRUE.
. . CALL DOCUHD(*1900)
. . WRITE(IPRT,97) IBUS,IM
. ...FIN
C .
...FIN
C
END
(FLECS Version 22.60 - PTI)
----------------------------------------
This is not Fotran Code but Flex Code. You have to translate this code to Fortran.
I am benchmarking the cache behaviour of two search algorithms that operate on a sorted range of items with Cachegrind. I have n items in a vector, and another vector that holds all valid indices. I use std::random_shuffle on the second vector, and do then perform n successful lookups on the items in the first vector. The function I am benchmarking looks roughly as follows:
template <typename Iterator>
void lookup_in_random_order(Iterator begin, Iterator end)
{
const std::size_t N = std::distance(begin, end);
std::vector<std::size_t> idx(N);
std::iota(idx.begin(), idx.end(), 0);
std::srand(std::time(0));
std::random_shuffle(idx.begin(), idx.end());
// Warm the cache -- I don't care about measuring this loop.
for(std::size_t i = 0; i < N; ++i)
my_search(begin, end, idx[i]);
std::random_shuffle(idx.begin(), idx.end());
// This one I would care about!
for(std::size_t i = 0; i < N; ++i)
{
int s = idx[i];
// Especially this line, of course.
my_search(begin, end, s);
}
}
I compile my code with g++ (with -g and -O2). I run Cachegrind and then cg_annotate. I get something like the following:
Ir I1mr ILmr Dr D1mr DLmr Dw D1mw DLmw
. . . . . . . . . template <typename Iterator>
17 2 2 0 0 0 6 0 0 void lookup_in_random_order(Iterator begin, Iterator end)
. . . . . . . . . {
. . . . . . . . . const std::size_t N = std::distance(begin, end);
. . . . . . . . . std::vector<std::size_t> idx(N);
. . . . . . . . . std::iota(idx.begin(), idx.end(), 0);
. . . . . . . . .
4 0 0 0 0 0 2 1 1 std::srand(std::time(0));
. . . . . . . . . std::random_shuffle(idx.begin(), idx.end());
. . . . . . . . .
3,145,729 0 0 0 0 0 0 0 0 for(std::size_t i = 0; i < N; ++i)
. . . . . . . . . my_search(begin, end, idx[i]);
. . . . . . . . .
. . . . . . . . . std::random_shuffle(idx.begin(), idx.end());
. . . . . . . . .
3,145,729 1 1 0 0 0 0 0 0 for(std::size_t i = 0; i < N; ++i)
. . . . . . . . . {
1,048,575 0 0 1,048,575 132,865 131,065 0 0 0 int s = idx[i];
. . . . . . . . . my_search(begin, end, s);
. . . . . . . . . }
7 0 0 6 1 1 0 0 0 }
For some reason, some lines (especially the most interesting one!) consist of dots. Now, the Cachegrind manual says "Events not applicable for a line are represented by a dot. This is useful for distinguishing between an event which cannot happen, and one which can but did not."
How should this be interpreted? My first idea was that maybe the compiler optimizes my searches away. I thought this cannot be, because the program did spend quite a bit of time running. Still, I tried compiling without the -O2 flag and it seemed to work in a sense that now every line with a call to my_search recorded some numbers (no dots anymore!). However, this doesn't seem like the right way to go for obvious reasons.
In general, is there a way I can tell Cachegrind that "look at this line especially, I am very interested how many cache misses it causes"?
My guess is that with O2 it allows the compiler to perform automatic inlining of the functions where you see the dots. Cachegrind will not see the inlined function calls as the calls have dissappeared. Try "-fno-inline" (Compiler options)
Of course you will probably have different cache performance numbers with and without inlining.