Skip to content

Commit 9379690

Browse files
committed
add new arguments for sitrep, refactor internal workings into smaller functions that are much easier to reason with
1 parent d3fcacd commit 9379690

File tree

3 files changed

+310
-217
lines changed

3 files changed

+310
-217
lines changed

DESCRIPTION

+1
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,5 @@ Collate:
137137
'write-logfiles.R'
138138
'zzz.R'
139139
'internals.R'
140+
'greta-sitrep.R'
140141
LazyData: true

R/greta-sitrep.R

+309
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,309 @@
1+
#' Greta Situation Report
2+
#'
3+
#' This checks if Python, Tensorflow, Tensorflow Probability, and the greta
4+
#' conda environment are available, and also loads and initialises python
5+
#'
6+
#' @param verbosity character. How verbose the output of the situation report.
7+
#' Possible options: "minimal" (default), "detailed", and "quiet". "Minimal"
8+
#' provides just information in python version, tensorflow version,
9+
#' tensorflow proability, and whether greta conda environment is available.
10+
#' "Quiet" presents no information, but prepares greta to be used. "Detailed"
11+
#' gives information on the version and path for R, greta, python,
12+
#' tensorflow, tensorflow probability, the greta conda environment, and a
13+
#' statement on greta usability.
14+
#' @return Message on greta situation report. See "verbsoity" parameter details
15+
#' above for more information.
16+
#' @export
17+
#'
18+
#' @examples
19+
#' \dontrun{
20+
#' greta_sitrep()
21+
#' }
22+
greta_sitrep <- function(verbosity = c("minimal", "detailed", "quiet")){
23+
24+
verbosity <- rlang::arg_match(
25+
arg = verbosity,
26+
values = c("minimal", "detailed", "quiet"),
27+
error_arg = "verbosity"
28+
)
29+
30+
switch(
31+
verbosity,
32+
minimal = minimal_sitrep(),
33+
detailed = detailed_sitrep(),
34+
quiet = quiet_sitrep()
35+
)
36+
37+
38+
}
39+
40+
check_if_python_available <- function(){
41+
check_if_software_available(
42+
software_available = have_python(),
43+
version = reticulate::py_version(),
44+
software_name = "python"
45+
)
46+
}
47+
48+
check_if_tf_available <- function(){
49+
check_if_software_available(
50+
software_available = have_tf(),
51+
version = version_tf(),
52+
software_name = "TensorFlow"
53+
)
54+
}
55+
56+
check_if_tfp_available <- function(){
57+
check_if_software_available(
58+
software_available = have_tfp(),
59+
version = version_tfp(),
60+
software_name = "TensorFlow Probability"
61+
)
62+
}
63+
64+
check_if_greta_conda_env_available <- function(){
65+
check_if_software_available(software_available = have_greta_conda_env(),
66+
software_name = "greta conda environment")
67+
68+
}
69+
70+
software_availability <- function(){
71+
software_available <- c(
72+
python = have_python(),
73+
tf = have_tf(),
74+
tfp = have_tfp(),
75+
greta_env = have_greta_conda_env()
76+
)
77+
software_available
78+
}
79+
80+
81+
get_current_ideal_deps <- function(){
82+
83+
software_version <- data.frame(
84+
software = c(
85+
"python",
86+
"tfp",
87+
"tf"
88+
),
89+
current = c(
90+
paste0(reticulate::py_version()),
91+
paste0(version_tf()),
92+
paste0(version_tfp())
93+
),
94+
# versions must be at least this version
95+
ideal = c(
96+
"3.8",
97+
"2.15.0",
98+
"0.23.0"
99+
)
100+
)
101+
102+
software_version$match <- c(
103+
compareVersion(software_version$current[1], software_version$ideal[1]) >= 0,
104+
compareVersion(software_version$current[2], software_version$ideal[2]) >= 0,
105+
compareVersion(software_version$current[3], software_version$ideal[3]) >= 0
106+
)
107+
108+
software_version
109+
110+
}
111+
112+
check_greta_ready_to_use <- function(software_available){
113+
114+
if (!all(software_available)) {
115+
check_tf_version("warn")
116+
} else if (all(software_available)) {
117+
software_version <- get_current_ideal_deps()
118+
119+
if (all(software_version$match)){
120+
check_tf_version("none")
121+
cli::cli_alert_info("{.pkg greta} is ready to use!",
122+
wrap = TRUE)
123+
} else {
124+
check_tf_version("warn")
125+
}
126+
127+
}
128+
129+
}
130+
131+
132+
minimal_sitrep <- function(){
133+
134+
check_if_python_available()
135+
check_if_tf_available()
136+
check_if_tfp_available()
137+
check_if_greta_conda_env_available()
138+
139+
software_available <- software_availability()
140+
141+
check_greta_ready_to_use(software_available)
142+
143+
}
144+
145+
detailed_sitrep <- function(){
146+
147+
config_info <- reticulate::py_config()
148+
149+
cli::cli_h1("R")
150+
cli::cli_ul("version: {.val {getRversion()}}")
151+
cli::cli_ul("path: {R.home()}")
152+
cli::cli_h1("{.pkg greta}")
153+
cli::cli_ul("version: {.val {packageVersion('greta')}}")
154+
cli::cli_ul("path: {.val {find.package('greta')}}")
155+
156+
cli::cli_h1("{.pkg python}")
157+
check_if_python_available()
158+
cli::cli_ul("path: {.val {find.package('greta')}}")
159+
cli::cli_ul("path: {.val {reticulate::miniconda_path()}}")
160+
161+
cli::cli_h1("{.pkg TensorFlow}")
162+
check_if_tf_available()
163+
cli::cli_ul("R path: {.path {find.package('tensorflow')}}")
164+
cli::cli_ul("python path: {.val {find.package('greta')}}")
165+
166+
cli::cli_h1("{.pkg TensorFlow Probability}")
167+
check_if_tfp_available()
168+
cli::cli_ul("R path: {.path {find.package('tensorflow')}}")
169+
cli::cli_ul("python path: {.val {find.package('greta')}}")
170+
171+
cli::cli_h1("{.pkg greta conda environment}")
172+
check_if_greta_conda_env_available()
173+
show_greta_conda_env_path()
174+
175+
software_available <- software_availability()
176+
177+
check_greta_ready_to_use(software_available)
178+
179+
}
180+
181+
quiet_sitrep <- function(){
182+
183+
suppressMessages({
184+
185+
software_available <- software_availability()
186+
187+
check_greta_ready_to_use(software_available)
188+
})
189+
190+
}
191+
192+
check_if_software_available <- function(software_available,
193+
version = NULL,
194+
ideal_version = NULL,
195+
software_name){
196+
197+
cli::cli_process_start("checking if {.pkg {software_name}} available")
198+
# if the software is detected
199+
200+
if (!software_available) {
201+
cli::cli_process_failed(
202+
msg_failed = "{.pkg {software_name}} not available"
203+
)
204+
}
205+
206+
if (software_available) {
207+
208+
if (is.null(ideal_version) & !is.null(version)){
209+
cli::cli_process_done(
210+
msg_done = "{.pkg {software_name}} (v{version}) available"
211+
)
212+
}
213+
214+
# if it has a version and ideal version
215+
has_ideal_version <- !is.null(version) & !is.null(ideal_version)
216+
if (has_ideal_version){
217+
version_chr <- paste0(version)
218+
version_match <- compareVersion(version_chr, ideal_version) == 0
219+
220+
if (version_match){
221+
cli::cli_process_done(
222+
msg_done = "{.pkg {software_name}} (v{version}) available"
223+
)
224+
}
225+
if (!version_match){
226+
cli::cli_process_failed(
227+
msg_failed = "{.pkg {software_name}} available, \\
228+
however {.strong {ideal_version}} is needed and \\
229+
{.strong {version}} was detected"
230+
)
231+
}
232+
# if there is no version for the software
233+
} else if (is.null(version)){
234+
cli::cli_process_done(
235+
msg_done = "{.pkg {software_name}} available"
236+
)
237+
}
238+
}
239+
}
240+
241+
compare_version_vec <- Vectorize(
242+
FUN = compareVersion,
243+
vectorize.args = "b",
244+
SIMPLIFY = TRUE
245+
)
246+
247+
# find out whether the usr has conda installed and visible
248+
#' @importFrom reticulate conda_binary
249+
have_conda <- function() {
250+
conda_bin <- tryCatch(reticulate::conda_binary("auto"),
251+
error = function(e) NULL
252+
)
253+
!is.null(conda_bin)
254+
}
255+
256+
#' @importFrom reticulate py_available
257+
have_python <- function() {
258+
tryCatch(
259+
expr = reticulate::py_available(initialize = TRUE),
260+
error = function(e) FALSE
261+
)
262+
}
263+
264+
#' @importFrom reticulate py_module_available
265+
have_tfp <- function() {
266+
is_tfp_available <- reticulate::py_module_available("tensorflow_probability")
267+
268+
if (is_tfp_available) {
269+
270+
pkg <- reticulate::import("pkg_resources")
271+
tfp_version <- pkg$get_distribution("tensorflow_probability")$version
272+
is_tfp_available <- utils::compareVersion("0.15.0", tfp_version) <= 0
273+
274+
}
275+
276+
return(is_tfp_available)
277+
278+
}
279+
280+
#' @importFrom reticulate py_module_available
281+
have_tf <- function() {
282+
is_tf_available <- reticulate::py_module_available("tensorflow")
283+
284+
if (is_tf_available) {
285+
286+
tf_version <- suppressMessages(tf$`__version__`)
287+
is_tf_available <- utils::compareVersion("2.9.0", tf_version) <= 0
288+
289+
}
290+
291+
return(is_tf_available)
292+
293+
}
294+
295+
version_tf <- function(){
296+
if (have_tf()) {
297+
tf$`__version__`
298+
} else {
299+
NULL
300+
}
301+
}
302+
303+
version_tfp <- function(){
304+
if (have_tfp()) {
305+
tfp$`__version__`
306+
} else {
307+
NULL
308+
}
309+
}

0 commit comments

Comments
 (0)