Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions nCompiler/R/Rexecution.R
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ nAs <- function(object, type) {
scalar_type <- storage.mode(object)
input_dims <- dim(object) %||% length(object)
output_dims <- make_nAs_output_dims(input_dims, output_nDim)
if(!length(output_dims)) output_dims <- 1
value_dims <- dim(value) %||% length(value)
if(!all.equal(output_dims, value_dims))
stop("value doesn't conform to type in nAs<- assignment")
Expand Down
13 changes: 8 additions & 5 deletions nCompiler/R/compile_generateCpp.R
Original file line number Diff line number Diff line change
Expand Up @@ -617,18 +617,21 @@ inGenCppEnv(
}
)

inGenCppEnv(
nCompiler:::inGenCppEnv(
As <- function(code, symTab) {
obj_cpp <- compile_generateCpp(code$args[[1]], symTab)
tgt_type <- code$type$type
tgt_nDim <- code$type$nDim
target_sym <- code$type
# tgt_type <- code$type$type
# tgt_nDim <- code$type$nDim
use_stm <- isTRUE(code$aux$useSTM)
is_lhs <- isTRUE(code$aux$onLHS)

tgt_cpp <- as_op_scalarToCpp(tgt_type)
#tgt_cpp <- as_op_scalarToCpp(target_sym$type)
mode_arg <- if(is_lhs) ', AsMode::LHS' else if(use_stm) ', AsMode::STM' else ''
# All proxy types expose operator()() — always append ().
paste0('as_nC<', tgt_cpp, ', ', tgt_nDim, mode_arg, '>(', obj_cpp, ')()')
# paste0('as_nC<', tgt_cpp, ', ', tgt_nDim, mode_arg, '>(', obj_cpp, ')()')
paste0('as_nC<', target_sym$genCppVar()$generate(""),
mode_arg, '>(', obj_cpp, ')()')
}
)

Expand Down
22 changes: 21 additions & 1 deletion nCompiler/R/compile_labelAbstractTypes.R
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ inLabelAbstractTypesEnv(
# }
# )

inLabelAbstractTypesEnv(
nCompiler:::inLabelAbstractTypesEnv(
DoubleBracket <- function(code, symTab, auxEnv, handlingInfo) {
# specializations from generic will have already been handled
# e.g obj[[1]] where obj defines its own "[[" operator definition (opDef).
Expand All @@ -338,6 +338,26 @@ inLabelAbstractTypesEnv(
useArgs[1] <- FALSE # already processed
inserts <- recurse_labelAbstractTypes(code, symTab, auxEnv,
handlingInfo, useArgs = useArgs)
if(inherits(code$args[[1]]$type, "symbolNC")) {
if(isTRUE(code$args[[2]]$isLiteral)) {
# This case is from the end of DollarSign (could be combined)
innerName <- as.character(code$args[[2]]$name)
symbol <- NCinternals(code$args[[1]]$type$NCgenerator)$symbolTable$getSymbol(innerName, inherits=TRUE)
if(is.null(symbol))
stop(exprClassProcessingErrorMsg(
code,
paste0('member variable ', innerName, ' of ', code$args[[1]]$name, ' could not be found.')
), call. = FALSE)
code$type <- symbol$clone(deep = TRUE)
code$name <- '->member'
} else {
code$type <- symbolETaccBase$new(name = '')
code$name <- '->method'
insertArg(code, 2, exprClass$new(name = 'access', isName = TRUE, isCall = FALSE,
isLiteral = FALSE, isAssign = FALSE))
}
return(if(length(inserts) == 0) NULL else inserts)
}
# return type of x[[i]] is the element type of x
# and return type of `[[<-`(x, i, value) is the type of value,
#. which is also the element type of x, so both cases have same return type
Expand Down
6 changes: 6 additions & 0 deletions nCompiler/R/cppDefs_variables.R
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,12 @@ cppNcppVec <- function(name = character(),
templateArgs = list(elementVar))
}

cppETaccBase <- function(name = character()) {
cppVarFullClass$new(name = name,
baseType = "std::unique_ptr",
templateArgs = list("ETaccessorBase"))
}

cppEigenTensorRef <- function(name = character(),
nDim,
scalarType) {
Expand Down
54 changes: 21 additions & 33 deletions nCompiler/R/symbolTable.R
Original file line number Diff line number Diff line change
Expand Up @@ -442,39 +442,27 @@ symbolNcppVec <- R6::R6Class(
)
)


## I think this was and old idea
## symbolList <- R6::R6Class(
## classname = "symbolList",
## inherit = symbolBase,
## portable = TRUE,
## public = list(
## size = NULL,
## initialize = function(..., size = NA) {
## super$initialize(...)
## self$type = 'list'
## self$size <- size
## self
## },
## shortPrint = function() {
## 'List'
## },
## print = function() {
## if(is.null(self$size)) {
## writeLines(
## paste0(self$name, ': ', self$type, ' size = (uninitialized),')
## )
## } else {
## writeLines(
## paste0(self$name, ': ', self$type, ' size = ', self$size)
## )
## }
## },
## genCppVar = function() {
## return(cppRcppList(name = self$name))
## }
## )
## )
symbolETaccBase <- R6::R6Class(
classname = "symbolETaccBase",
inherit = symbolBase,
portable = TRUE,
public = list(
initialize = function(name, isArg = FALSE) {
self$name <- name
self$type <- "ETaccessorBase"
self$isArg <- isArg
},
print = function() {
writeLines(paste0(self$name, ': symbolETaccBase (ETaccessorBase) '))
},
uniqueID = function(...) {
paste0("ETaccessorBase")
},
genCppVar = function() {
cppETaccBase(name = self$name)
}
)
)

symbolRcppType<- R6::R6Class(
classname = "symbolRcppType",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,46 @@
#include <unsupported/Eigen/CXX11/Tensor>
#include <type_traits>
#include <nCompiler/ET_ext/StridedTensorMap.h>
#include <nCompiler/ET_ext/post_Rcpp/tensorUtils.h>
#include <nCompiler/ET_ext/post_Rcpp/tensorFlex.h>

template<typename Scalar>
class ETaccessorTyped;

template<typename inDimsT, typename outDimsT>
void set_output_dims(const inDimsT &inDim, outDimsT &outDim,
size_t output_nDim) {
size_t in_nDim = inDim.size();
if(output_nDim >= in_nDim) {
for(size_t i = 0; i < in_nDim; ++i)
outDim[i] = inDim[i];
for(size_t i = in_nDim; i < output_nDim; ++i)
outDim[i] = 1;
} else {
size_t i_out = 0;
for(size_t i_in = 0; i_in < in_nDim; ++i_in) {
if(inDim[i_in] > 1) {
if(i_out >= output_nDim)
Rcpp::stop("Too many non-singleton dimensions for requested morphing to lower dimensional object.");
outDim[i_out++] = inDim[i_in];
}
}
for(; i_out < output_nDim; ++i_out)
outDim[i_out] = 1;
}
}

enum class AsMode { TM, STM, LHS };

// Forward declarations: proxy classes are defined in nC_as.h (included after
// this file). ETaccessorTyped::asTyped() returns them; because asTyped() is a
// template, instantiation is deferred to the call site where they are fully
// defined.
template<typename ViewType> class EmptyProxy;
template<typename Scalar> class EmptyScalarProxy;
template<typename TargetScalar, typename ViewType> class RHSCastProxy;
template<typename TargetScalar, typename ViewType> class CastingProxy;
template<typename TargetScalar, typename Scalar> class CastingScalarProxy;

// Virtual nDim-general methods (e.g. resize, conversions to and from SEXP).
class ETaccessorBase {
Expand Down Expand Up @@ -133,8 +160,11 @@ class ETaccessorTyped : public ETaccessorBase {

// Central dispatch for as() operations. Returns a proxy wrapping the
// appropriate view. All proxy types expose operator()() uniformly.
template<typename TargetScalar, int nDim, AsMode mode = AsMode::TM>
template<typename TargetType, AsMode mode = AsMode::TM,
std::enable_if_t<std::is_same_v<type_category_t<TargetType>, eigenTensor>, int> = 0>
auto asTyped() {
typedef typename Eigen::nDimTraits2<TargetType>::Scalar TargetScalar;
constexpr int nDim = Eigen::nDimTraits2<TargetType>::NumDimensions;
if constexpr (std::is_same_v<TargetScalar, Scalar>) {
if constexpr (mode == AsMode::TM)
return EmptyProxy<ETM<nDim>>(mapTyped<nDim>());
Expand All @@ -156,6 +186,17 @@ class ETaccessorTyped : public ETaccessorBase {
}
}

template<typename TargetType, AsMode mode = AsMode::TM,
std::enable_if_t<std::is_same_v<type_category_t<TargetType>, trueScalar>, int> = 0>
auto asTyped() {
typedef TargetType TargetScalar;
if constexpr (std::is_same_v<TargetScalar, Scalar>) {
return EmptyScalarProxy<TargetScalar>(scalarTyped());
} else {
return CastingScalarProxy<TargetScalar, Scalar>(scalarTyped());
}
}

template<int output_nDim>
ETM<output_nDim> mapTyped() {
//innate_nDim is the nDim of the object.
Expand All @@ -166,32 +207,10 @@ class ETaccessorTyped : public ETaccessorBase {
//but there both the LHS and RHS nDims are known at compile time.
//Here only the output_nDim is known at compile time.
//Also it looks like in checkAndSetupDims, RHS singletons are always dropped
typedef typename Eigen::internal::traits<ETM<output_nDim> >::Index Index;
// typedef typename Eigen::internal::traits<ETM<output_nDim> >::Index Index;
typedef typename ETM<output_nDim>::Dimensions output_Dimensions;
output_Dimensions outDim;
const auto intDims_ = this->intDims();
size_t innate_nDim = intDims_.size();
if(output_nDim >= innate_nDim) {
for(size_t i = 0; i < innate_nDim; ++i)
outDim[i] = intDims_[i];
if(output_nDim > innate_nDim) {
for(size_t i = innate_nDim; i < output_nDim; ++i)
outDim[i] = 1;
}
} else {
size_t i_out = 0;
for(size_t i_innate = 0 ; i_innate < innate_nDim; ++i_innate) {
if(intDims_[i_innate] > 1) {
if(i_out >= output_nDim) {
Rcpp::stop("Problem making a TensorMap from some form of access(): Too many non-singleton dimensions for the requested map dimensions.\n");
break;
} else {
outDim[i_out++] = intDims_[i_innate];
}
}
}
for( ; i_out < output_nDim; ++i_out ) outDim[i_out]=1;
}
set_output_dims(this->intDims(), outDim, output_nDim);
return ETM<output_nDim>(data(), outDim);
}
~ETaccessorTyped(){};
Expand Down Expand Up @@ -283,14 +302,6 @@ class ETaccessor<Eigen::Tensor<Scalar, nDim> > : public ETaccessorTyped<Scalar>
return wrap(obj);
}
ET &innerRef() {return obj;}
// Scalar &scalar() {
// Dimensions dim = obj.dimensions();
// for(int i = 0; i < nDim; ++i) {
// if(dim[i]!=1)
// Rcpp::stop("Invalid call to scalar() for ETaccessor with dimensions not all equal to 1.");
// }
// return *obj.data(); // would leak memory but will never be reached and may reduce compiler warnings
// }
ET &obj;
std::vector<int> intDims_;
};
Expand All @@ -308,7 +319,6 @@ class ETaccessorScalar : public ETaccessorTyped<Scalar> {
Rcpp::stop("Invalid call to ref() for ETaccessor to scalar.");
return *new Eigen::Tensor<double, 0>(); // bad memory mgmt (would leak) but will never be called. only to show compiler valid return.
}
//Scalar &scalar() {return obj;}
Scalar &obj;
std::vector<int> intDims_;
};
Expand All @@ -320,14 +330,6 @@ class ETaccessor<double> : public ETaccessorScalar<double> {
~ETaccessor() {};
};

// // CppAD header is not read by here, so this needs attention.
// template<>
// class ETaccessor<CppAD::AD<double> > : public ETaccessorScalar<CppAD::AD<double> > {
// public:
// ETaccessor(CppAD::AD<double> &obj_) : ETaccessorScalar(obj_) {};
// ~ETaccessor() {};
// };

template<>
class ETaccessor<int> : public ETaccessorScalar<int> {
public:
Expand All @@ -342,45 +344,13 @@ class ETaccessor<bool> : public ETaccessorScalar<bool> {
~ETaccessor() {};
};

// template<>
// class ETaccessor<double> : public ETaccessorTyped<double> {
// public:
// using Scalar = double;

// ETaccessor(Scalar &obj_) : obj(obj_) {};
// ~ETaccessor() {};
// Scalar *data() override {return &obj;}
// std::vector<int> &intDims() override {return intDims_;}
// void set(SEXP Sinput) override { obj = as<Scalar>(Sinput);}
// SEXP get() override {return wrap(obj);}
// Eigen::Tensor<double, 0> &ref() {
// Rcpp::stop("Invalid call to ref() for ETaccessor to scalar.");
// return *new Eigen::Tensor<double, 0>(); // bad memory mgmt (would leak) but will never be called. only to show compiler valid return.
// }
// Scalar &scalar() {return obj;}
// Scalar &obj;
// std::vector<int> intDims_;
// };

template<int nDim, typename Scalar>
Eigen::Tensor<Scalar, nDim> &ETaccessorBase::ref() {
auto castptr = dynamic_cast<ETaccessor<Eigen::Tensor<Scalar, nDim> >* >(this);
if(castptr == nullptr) Rcpp::stop("Problem creating a ref() from some form of access().\n");
return castptr->innerRef();
}

// template<typename Scalar>
// Scalar &ETaccessorBase::scalar() {
// auto castptr = dynamic_cast<ETaccessor<Scalar>* >(this);
// if(castptr == nullptr) Rcpp::stop("Problem creating a scalar() from some form of access().\n");
// return castptr->scalar();
// }

// template<typename Scalar, int nDim>
// auto access(Eigen::Tensor<Scalar, nDim> &x) -> ETaccessor<Eigen::Tensor<Scalar, nDim> >{
// return ETaccessor<Eigen::Tensor<Scalar, nDim> >(x);
// }

template<typename T>
auto ETaccess(T &x) -> ETaccessor<T>{
return ETaccessor<T>(x);
Expand Down
Loading
Loading