Skip to content

Commit

Permalink
We seem to really have to call the R/python level flush commands to
Browse files Browse the repository at this point in the history
ensure our "cout" reaches Jupyter notebooks in a timely fashion
  • Loading branch information
pralitp committed May 25, 2023
1 parent ebe5243 commit a4cb3e3
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 12 deletions.
1 change: 1 addition & 0 deletions R/query_library.R
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ wrap_get_query <- function() {
#' @return (string) The raw query from the query file with units set as an attribute
#' if specified.
#' @importFrom yaml read_yaml
#' @export
get_query <- wrap_get_query()


Expand Down
47 changes: 35 additions & 12 deletions inst/include/interp_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#include <exception>
#include <string>

// use boost::iostreams to wrap Interp API for cout
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/categories.hpp>

#if __has_include("Rcpp.h")
#define IS_INTERP_R
#define STRICT_R_HEADERS
Expand All @@ -13,9 +17,6 @@
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>

// use boost::iostreams to wrap Python's C API for cout
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/categories.hpp>
#include <boost/format.hpp>
#else
#error "Could not determine, or using an unknown interpreter. Only R and Python are currently supported."
Expand All @@ -32,6 +33,26 @@ class gcam_exception : public std::exception {
};

#if defined(USING_R)

/*!
* \brief Wrap Rprintf in a boost::iostreams so we can use a C++ interface.
* \details We couldn't just use Rcout directly because we need to add a flush
* for it to show up in a notebook in a timeley manner.
*/
class RStdoutSink {
public:
typedef char char_type;
typedef boost::iostreams::sink_tag category;

inline std::streamsize write(const char* aString, std::streamsize aSize) {
Rprintf("%.*s", aSize, aString);
// using R_FlushConsole() doesn't work for whatever reason
Rcpp::Function flush("flush.console");
flush();
return aSize;
}
};

namespace Interp {
using Rcpp::stop;
using Rcpp::warning;
Expand All @@ -42,7 +63,8 @@ namespace Interp {
using Rcpp::NumericMatrix;

inline std::ostream& getInterpCout() {
return Rcpp::Rcout;
static boost::iostreams::stream<RStdoutSink> sRCout;
return sRCout;
}

inline std::string extract(const Rcpp::String& aStr) {
Expand Down Expand Up @@ -101,15 +123,16 @@ namespace Interp {
*/
class PySysStdoutSink {
public:
typedef char char_type;
typedef boost::iostreams::sink_tag category;
typedef char char_type;
typedef boost::iostreams::sink_tag category;

inline std::streamsize write(const char* aString, std::streamsize aSize) {
const std::streamsize MAX_PY_SIZE = 1000;
std::streamsize actualSize = std::min(aSize, MAX_PY_SIZE);
PySys_WriteStdout((boost::format("%%.%1%s") % actualSize).str().c_str(), aString);
return actualSize;
}
inline std::streamsize write(const char* aString, std::streamsize aSize) {
const std::streamsize MAX_PY_SIZE = 1000;
std::streamsize actualSize = std::min(aSize, MAX_PY_SIZE);
PySys_WriteStdout((boost::format("%%.%1%s") % actualSize).str().c_str(), aString);
boost::python::call_method<void>(PySys_GetObject("stdout"), "flush");
return actualSize;
}
};

namespace Interp {
Expand Down

0 comments on commit a4cb3e3

Please sign in to comment.