Skip to content

Commit e2ad6de

Browse files
committed
.github/workflows/rchk.yml: New.
r/ Fix rchk warnings.
1 parent f648a04 commit e2ad6de

File tree

7 files changed

+129
-91
lines changed

7 files changed

+129
-91
lines changed

.github/workflows/R.yml

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -107,32 +107,6 @@ jobs:
107107
name: results-${{ runner.os }}-r${{ matrix.r }}
108108
path: r/check
109109

110-
rchk:
111-
if: false # Skip until https://github.com/r-lib/actions/issues/783
112-
needs: R-CMD-check
113-
runs-on: ubuntu-latest
114-
container:
115-
image: rhub/ubuntu-rchk
116-
options: --user=root
117-
118-
steps:
119-
- uses: actions/checkout@v4
120-
121-
- uses: r-lib/actions/run-rchk@v2
122-
with:
123-
setup-only: true
124-
125-
- run: ls -R /home/docker/R-svn/bin
126-
127-
- uses: r-lib/actions/setup-r-dependencies@v2
128-
with:
129-
extra-packages: any::rcmdcheck, local::., any::eaf
130-
working-directory: r
131-
132-
- uses: r-lib/actions/run-rchk@v2
133-
with:
134-
run-only: true
135-
136110
coverage:
137111
needs: R-CMD-check
138112
name: Coverage ${{ matrix.os }} (${{ matrix.r }})

.github/workflows/rchk.yml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# adapted from a similar check run by {arrow}
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
name: rchk
19+
20+
on:
21+
workflow_run:
22+
workflows: ['R']
23+
types:
24+
- completed
25+
branches-ignore: [gh-pages]
26+
paths:
27+
- ".github/workflows/rchk.yml"
28+
- "r/**"
29+
- 'c/Make*'
30+
- 'c/*.mk'
31+
- 'c/**/*.[ch]p?p?'
32+
33+
env:
34+
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
35+
_R_CHECK_FORCE_SUGGESTS_: false
36+
_R_CHECK_CRAN_INCOMING_REMOTE_: false
37+
38+
concurrency:
39+
group: ${{ github.workflow }}-${{ github.ref }}
40+
cancel-in-progress: true
41+
42+
jobs:
43+
rchk:
44+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
45+
runs-on: ubuntu-latest
46+
name: Run rchk
47+
steps:
48+
- uses: actions/checkout@v4
49+
- uses: r-lib/actions/setup-r@v2
50+
with:
51+
r-version: 'devel'
52+
53+
- name: Install minimal dependencies
54+
run: |
55+
install.packages(c("Rdpack","matrixStats"))
56+
shell: Rscript {0}
57+
working-directory: r
58+
59+
- name: Build
60+
run: |
61+
R CMD build --no-build-vignettes r
62+
mkdir packages
63+
mv moocore_*.tar.gz packages
64+
65+
- name: Run rchk
66+
run: |
67+
docker run -v `pwd`/packages:/rchk/packages kalibera/rchk:latest /rchk/packages/moocore_*.tar.gz |& tee rchk.out
68+
- name: Confirm that rchk has no errors
69+
# Suspicious call, [UP], and [PB] are all of the error types currently at
70+
# https://github.com/kalibera/cran-checks/tree/HEAD/rchk/results
71+
# though this might not be exhaustive, there does not appear to be a way to have rchk return an error code
72+
# CRAN also will remove some of the outputs (especially those related to Rcpp and strptime, e.g.
73+
# ERROR: too many states (abstraction error?))
74+
# https://github.com/kalibera/rchk
75+
run: |
76+
if [ $(grep -Fc "Suspicious call" rchk.out) -gt 0 ] || [ $(grep -F "[UP]" rchk.out | grep -Fvc "results will be incomplete") -gt 0 ] || [ $(grep -Fc "[PB]" rchk.out) -gt 0 ]; then
77+
echo "Found rchk errors"
78+
exit 1
79+
fi
80+
if: always()

r/DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ URL: https://multi-objective.github.io/moocore/r/, https://github.com/multi-obje
3232
LazyLoad: true
3333
LazyData: true
3434
Encoding: UTF-8
35-
RoxygenNote: 7.3.0
35+
RoxygenNote: 7.3.2
3636
Roxygen: list(markdown = TRUE,
3737
roclets = c("collate", "rd", "namespace",
3838
"doctest::dt_roclet"))

r/src/Rcommon.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@
99

1010
#define CHECK_ARG_IS_NUMERIC_VECTOR(A) \
1111
if (!Rf_isReal(A) || !Rf_isVector(A)) \
12-
Rf_error("Argument '" #A "' is not a numeric vector");
12+
Rf_error("Argument '" #A "' is not a numeric vector");
1313

1414
#define CHECK_ARG_IS_NUMERIC_MATRIX(A) \
1515
if (!Rf_isReal(A) || !Rf_isMatrix(A)) \
16-
Rf_error("Argument '" #A "' is not a numeric matrix");
16+
Rf_error("Argument '" #A "' is not a numeric matrix");
1717

1818
#define CHECK_ARG_IS_INT_VECTOR(A) \
1919
if (!Rf_isInteger(A) || !Rf_isVector(A)) \
20-
Rf_error("Argument '" #A "' is not an integer vector");
20+
Rf_error("Argument '" #A "' is not an integer vector");
2121

2222
#define CHECK_ARG_IS_LOGICAL_VECTOR(A) \
2323
if (!Rf_isLogical(A) || !Rf_isVector(A)) \
24-
Rf_error("Argument '" #A "' is not a logical vector");
24+
Rf_error("Argument '" #A "' is not a logical vector");
2525

2626
/* The C API of R is awfully ugly and unpractical (and poorly
2727
documented). These wrappers make it a little more bearable. */

r/src/Rmoocore.c

Lines changed: 23 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
#include "Rcommon.h"
22
#include "eaf.h"
33

4-
#define DECLARE_CALL(RET_TYPE, NAME, ...) \
5-
extern RET_TYPE NAME(__VA_ARGS__);
4+
#define DECLARE_CALL(NAME, ...) extern SEXP NAME(__VA_ARGS__);
65
#include "init.h"
76
#undef DECLARE_CALL
87

@@ -52,8 +51,7 @@ compute_eaf_C(SEXP DATA, SEXP CUMSIZES, SEXP PERCENTILE)
5251
eaf_t **eaf = compute_eaf_helper(DATA, nobj, cumsizes, nruns, percentile, nlevels);
5352
int totalpoints = eaf_totalpoints (eaf, nlevels);
5453

55-
SEXP mat;
56-
PROTECT(mat = Rf_allocMatrix(REALSXP, totalpoints, nobj + 1));
54+
SEXP mat = PROTECT(Rf_allocMatrix(REALSXP, totalpoints, nobj + 1));
5755
eaf2matrix_R(REAL(mat), eaf, nobj, totalpoints, percentile, nlevels);
5856
eaf_free(eaf, nlevels);
5957
UNPROTECT(1);
@@ -271,8 +269,7 @@ R_read_datasets(SEXP FILENAME)
271269
const int ntotal = cumsizes[nruns - 1];
272270

273271
/* FIXME: Is this the fastest way to transfer a matrix from C to R ? */
274-
SEXP DATA;
275-
PROTECT(DATA = Rf_allocMatrix(REALSXP, ntotal, nobj + 1));
272+
SEXP DATA = PROTECT(Rf_allocMatrix(REALSXP, ntotal, nobj + 1));
276273
double *rdata = REAL(DATA);
277274
matrix_transpose_double (rdata, data, ntotal, nobj);
278275

@@ -290,7 +287,7 @@ R_read_datasets(SEXP FILENAME)
290287

291288
#include "nondominated.h"
292289

293-
void
290+
SEXP
294291
normalise_C(SEXP DATA, SEXP RANGE, SEXP LBOUND, SEXP UBOUND, SEXP MAXIMISE)
295292
{
296293
int nprotected = 0;
@@ -310,6 +307,7 @@ normalise_C(SEXP DATA, SEXP RANGE, SEXP LBOUND, SEXP UBOUND, SEXP MAXIMISE)
310307
lbound, ubound);
311308
free (maximise);
312309
UNPROTECT(nprotected);
310+
return R_NilValue;
313311
}
314312

315313
SEXP
@@ -356,15 +354,12 @@ pareto_ranking_C(SEXP DATA)
356354
SEXP
357355
hypervolume_C(SEXP DATA, SEXP REFERENCE)
358356
{
359-
int nprotected = 0;
360357
/* We transpose the matrix before calling this function. */
361358
SEXP_2_DOUBLE_MATRIX(DATA, data, nobj, npoint);
362359
SEXP_2_DOUBLE_VECTOR(REFERENCE, reference, reference_len);
363360
assert (nobj == reference_len);
364-
new_real_vector(hv, 1);
365-
hv[0] = fpli_hv(data, nobj, npoint, reference);
366-
UNPROTECT (nprotected);
367-
return Rexp(hv);
361+
double hv = fpli_hv(data, nobj, npoint, reference);
362+
return Rf_ScalarReal(hv);
368363
}
369364

370365
SEXP
@@ -385,20 +380,16 @@ hv_contributions_C(SEXP DATA, SEXP REFERENCE)
385380
SEXP
386381
rect_weighted_hv2d_C(SEXP DATA, SEXP RECTANGLES)
387382
{
388-
int nprotected = 0;
389383
/* We transpose the matrix before calling this function. */
390384
SEXP_2_DOUBLE_MATRIX(DATA, data, nobj, npoint);
391385
SEXP_2_DOUBLE_MATRIX(RECTANGLES, rectangles, unused, rectangles_nrow);
392-
new_real_vector(hv, 1);
393-
hv[0] = rect_weighted_hv2d(data, npoint, rectangles, rectangles_nrow);
394-
UNPROTECT (nprotected);
395-
return Rexp(hv);
386+
double hv = rect_weighted_hv2d(data, npoint, rectangles, rectangles_nrow);
387+
return Rf_ScalarReal(hv);
396388
}
397389

398390
SEXP
399391
preprocess_rectangles_C(SEXP RECTANGLES, SEXP REFERENCE)
400392
{
401-
int nprotected = 0;
402393
/* We transpose the matrix before calling this function. */
403394
SEXP_2_DOUBLE_MATRIX(RECTANGLES, rectangles, ncol, nrow);
404395
SEXP_2_DOUBLE_VECTOR(REFERENCE, reference, reference_len);
@@ -411,7 +402,7 @@ preprocess_rectangles_C(SEXP RECTANGLES, SEXP REFERENCE)
411402
rectangles[k * ncol + 3] = MIN(rectangles[k * ncol + 3], reference[1]);
412403
}
413404
int skip_nrow = 0;
414-
int * skip = (int *) malloc(nrow * sizeof(int));
405+
int * skip = (int *) R_alloc(nrow, sizeof(int));
415406
for (int k = 0; k < nrow; k++) {
416407
bool empty = (rectangles[k * ncol + 0] == rectangles[k * ncol + 2]
417408
|| rectangles[k * ncol + 1] == rectangles[k * ncol + 3]);
@@ -420,8 +411,6 @@ preprocess_rectangles_C(SEXP RECTANGLES, SEXP REFERENCE)
420411
}
421412

422413
if (skip_nrow == 0) {
423-
free(skip);
424-
UNPROTECT(nprotected);
425414
return RECTANGLES;
426415
}
427416
int new_nrow = nrow - skip_nrow;
@@ -440,8 +429,7 @@ preprocess_rectangles_C(SEXP RECTANGLES, SEXP REFERENCE)
440429
k = skip[s] + 1;
441430
}
442431
}
443-
free(skip);
444-
UNPROTECT(nprotected + 1);
432+
UNPROTECT(1);
445433
return R_dest;
446434
}
447435

@@ -450,7 +438,6 @@ preprocess_rectangles_C(SEXP RECTANGLES, SEXP REFERENCE)
450438
SEXP
451439
whv_hype_C(SEXP DATA, SEXP IDEAL, SEXP REFERENCE, SEXP NSAMPLES, SEXP DIST, SEXP SEED, SEXP MU)
452440
{
453-
int nprotected = 0;
454441
SEXP_2_DOUBLE_MATRIX(DATA, data, nobj, npoints);
455442
SEXP_2_DOUBLE_VECTOR(IDEAL, ideal, ideal_len);
456443
SEXP_2_DOUBLE_VECTOR(REFERENCE, reference, reference_len);
@@ -460,20 +447,19 @@ whv_hype_C(SEXP DATA, SEXP IDEAL, SEXP REFERENCE, SEXP NSAMPLES, SEXP DIST, SEXP
460447
SEXP_2_STRING(DIST, dist_type);
461448
SEXP_2_UINT32(SEED, seed);
462449

463-
new_real_vector(hv, 1);
450+
double hv;
464451
if (0 == strcmp(dist_type, "uniform")) {
465-
hv[0] = whv_hype_unif(data, npoints, ideal, reference, nsamples, seed);
452+
hv = whv_hype_unif(data, npoints, ideal, reference, nsamples, seed);
466453
} else if (0 == strcmp(dist_type, "exponential")) {
467454
const double * mu = REAL(MU);
468-
hv[0] = whv_hype_expo(data, npoints, ideal, reference, nsamples, seed, mu[0]);
455+
hv = whv_hype_expo(data, npoints, ideal, reference, nsamples, seed, mu[0]);
469456
} else if (0 == strcmp(dist_type, "point")) {
470457
const double * mu = REAL(MU);
471-
hv[0] = whv_hype_gaus(data, npoints, ideal, reference, nsamples, seed, mu);
458+
hv = whv_hype_gaus(data, npoints, ideal, reference, nsamples, seed, mu);
472459
} else {
473460
Rf_error("unknown 'dist' value: %s", dist_type);
474461
}
475-
UNPROTECT (nprotected);
476-
return Rexp(hv);
462+
return Rf_ScalarReal(hv);
477463
}
478464

479465
#include "epsilon.h"
@@ -492,7 +478,6 @@ static inline SEXP
492478
unary_metric_ref(SEXP DATA, SEXP REFERENCE, SEXP MAXIMISE,
493479
enum unary_metric_t metric, SEXP EXTRA)
494480
{
495-
int nprotected = 0;
496481
/* We transpose the matrix before calling this function. */
497482
SEXP_2_DOUBLE_MATRIX(DATA, data, nobj, npoint);
498483
double *ref = REAL(REFERENCE);
@@ -501,32 +486,31 @@ unary_metric_ref(SEXP DATA, SEXP REFERENCE, SEXP MAXIMISE,
501486
SEXP_2_LOGICAL_BOOL_VECTOR(MAXIMISE, maximise, maximise_len);
502487
assert (nobj == maximise_len);
503488

504-
new_real_vector(value, 1);
489+
double value;
505490
switch (metric) {
506491
case EPSILON_ADD:
507-
value[0] = epsilon_additive (data, nobj, npoint, ref, ref_size, maximise);
492+
value = epsilon_additive (data, nobj, npoint, ref, ref_size, maximise);
508493
break;
509494
case EPSILON_MUL:
510-
value[0] = epsilon_mult (data, nobj, npoint, ref, ref_size, maximise);
495+
value = epsilon_mult (data, nobj, npoint, ref, ref_size, maximise);
511496
break;
512497
case INV_GD:
513-
value[0] = IGD (data, nobj, npoint, ref, ref_size, maximise);
498+
value = IGD (data, nobj, npoint, ref, ref_size, maximise);
514499
break;
515500
case INV_GDPLUS:
516-
value[0] = IGD_plus (data, nobj, npoint, ref, ref_size, maximise);
501+
value = IGD_plus (data, nobj, npoint, ref, ref_size, maximise);
517502
break;
518503
case AVG_HAUSDORFF: {
519504
SEXP_2_INT(EXTRA, p);
520-
value[0] = avg_Hausdorff_dist (data, nobj, npoint, ref, ref_size, maximise, p);
505+
value = avg_Hausdorff_dist (data, nobj, npoint, ref, ref_size, maximise, p);
521506
break;
522507
}
523508
default:
524509
Rf_error("unknown unary metric");
525510
}
526511

527512
free (maximise);
528-
UNPROTECT (nprotected);
529-
return Rexp(value);
513+
return Rf_ScalarReal(value);
530514
}
531515

532516
SEXP

r/src/init.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
88
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
99

10-
#define DECLARE_CALL(RET_TYPE, NAME, ...) \
11-
extern RET_TYPE NAME(__VA_ARGS__);
10+
#define DECLARE_CALL(NAME, ...) \
11+
extern SEXP NAME(__VA_ARGS__);
1212
#include "init.h"
1313
#undef DECLARE_CALL
1414

1515

16-
#define DECLARE_CALL(RET_TYPE, NAME, ...) \
16+
#define DECLARE_CALL(NAME, ...) \
1717
{#NAME, (DL_FUNC) &NAME, VA_NARGS(__VA_ARGS__)},
1818

1919
static const R_CallMethodDef CallEntries[] = {

r/src/init.h

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
/* .Call calls */
2-
DECLARE_CALL(SEXP, compute_eaf_C, SEXP DATA, SEXP CUMSIZES, SEXP PERCENTILE)
3-
DECLARE_CALL(SEXP, compute_eafdiff_C, SEXP DATA, SEXP CUMSIZES, SEXP INTERVALS)
4-
DECLARE_CALL(SEXP, compute_eafdiff_polygon_C, SEXP DATA, SEXP CUMSIZES, SEXP INTERVALS)
5-
DECLARE_CALL(SEXP, compute_eafdiff_rectangles_C, SEXP DATA, SEXP CUMSIZES, SEXP INTERVALS)
6-
DECLARE_CALL(SEXP, R_read_datasets, SEXP FILENAME)
7-
DECLARE_CALL(SEXP, hypervolume_C, SEXP DATA, SEXP REFERENCE)
8-
DECLARE_CALL(SEXP, hv_contributions_C, SEXP DATA, SEXP REFERENCE)
9-
DECLARE_CALL(void, normalise_C, SEXP DATA, SEXP RANGE, SEXP LBOUND, SEXP UBOUND, SEXP MAXIMISE)
10-
DECLARE_CALL(SEXP, is_nondominated_C, SEXP DATA, SEXP MAXIMISE, SEXP KEEP_WEAKLY)
11-
DECLARE_CALL(SEXP, pareto_ranking_C, SEXP DATA)
12-
DECLARE_CALL(SEXP, epsilon_mul_C, SEXP DATA, SEXP REFERENCE, SEXP MAXIMISE)
13-
DECLARE_CALL(SEXP, epsilon_add_C, SEXP DATA, SEXP REFERENCE, SEXP MAXIMISE)
14-
DECLARE_CALL(SEXP, igd_C, SEXP DATA, SEXP REFERENCE, SEXP MAXIMISE)
15-
DECLARE_CALL(SEXP, igd_plus_C, SEXP DATA, SEXP REFERENCE, SEXP MAXIMISE)
16-
DECLARE_CALL(SEXP, avg_hausdorff_dist_C, SEXP DATA, SEXP REFERENCE, SEXP MAXIMISE, SEXP P)
17-
DECLARE_CALL(SEXP, rect_weighted_hv2d_C, SEXP DATA, SEXP RECTANGLES)
18-
DECLARE_CALL(SEXP, whv_hype_C, SEXP DATA, SEXP IDEAL, SEXP REFERENCE, SEXP NSAMPLES, SEXP DIST, SEXP SEED, SEXP MU)
19-
DECLARE_CALL(SEXP, preprocess_rectangles_C, SEXP RECTANGLES, SEXP REFERENCE)
2+
DECLARE_CALL(compute_eaf_C, SEXP DATA, SEXP CUMSIZES, SEXP PERCENTILE)
3+
DECLARE_CALL(compute_eafdiff_C, SEXP DATA, SEXP CUMSIZES, SEXP INTERVALS)
4+
DECLARE_CALL(compute_eafdiff_polygon_C, SEXP DATA, SEXP CUMSIZES, SEXP INTERVALS)
5+
DECLARE_CALL(compute_eafdiff_rectangles_C, SEXP DATA, SEXP CUMSIZES, SEXP INTERVALS)
6+
DECLARE_CALL(R_read_datasets, SEXP FILENAME)
7+
DECLARE_CALL(hypervolume_C, SEXP DATA, SEXP REFERENCE)
8+
DECLARE_CALL(hv_contributions_C, SEXP DATA, SEXP REFERENCE)
9+
DECLARE_CALL(normalise_C, SEXP DATA, SEXP RANGE, SEXP LBOUND, SEXP UBOUND, SEXP MAXIMISE)
10+
DECLARE_CALL(is_nondominated_C, SEXP DATA, SEXP MAXIMISE, SEXP KEEP_WEAKLY)
11+
DECLARE_CALL(pareto_ranking_C, SEXP DATA)
12+
DECLARE_CALL(epsilon_mul_C, SEXP DATA, SEXP REFERENCE, SEXP MAXIMISE)
13+
DECLARE_CALL(epsilon_add_C, SEXP DATA, SEXP REFERENCE, SEXP MAXIMISE)
14+
DECLARE_CALL(igd_C, SEXP DATA, SEXP REFERENCE, SEXP MAXIMISE)
15+
DECLARE_CALL(igd_plus_C, SEXP DATA, SEXP REFERENCE, SEXP MAXIMISE)
16+
DECLARE_CALL(avg_hausdorff_dist_C, SEXP DATA, SEXP REFERENCE, SEXP MAXIMISE, SEXP P)
17+
DECLARE_CALL(rect_weighted_hv2d_C, SEXP DATA, SEXP RECTANGLES)
18+
DECLARE_CALL(whv_hype_C, SEXP DATA, SEXP IDEAL, SEXP REFERENCE, SEXP NSAMPLES, SEXP DIST, SEXP SEED, SEXP MU)
19+
DECLARE_CALL(preprocess_rectangles_C, SEXP RECTANGLES, SEXP REFERENCE)

0 commit comments

Comments
 (0)