40#ifndef BERTINI_SLP_HPP
41#define BERTINI_SLP_HPP
57#include <boost/serialization/utility.hpp>
58#include <boost/serialization/split_member.hpp>
222 constexpr size_t kOpcodeMask = (
static_cast<size_t>(1) << 17) - 1;
223 constexpr size_t kArg0Real =
static_cast<size_t>(1) << 20;
224 constexpr size_t kArg1Real =
static_cast<size_t>(1) << 21;
225 constexpr size_t kOutReal =
static_cast<size_t>(1) << 22;
241 template <
typename Archive>
242 void serialize(Archive& ar,
const unsigned ) {
262 template <
typename Archive>
263 void serialize(Archive& ar,
const unsigned ) {
284 template <
typename Archive>
285 void serialize(Archive& ar,
const unsigned ) {
337 template <
typename Archive>
338 void serialize(Archive& ar,
const unsigned ) {
339 int k =
static_cast<int>(
kind);
363 template<
typename NumT>
364 std::vector<NumT>&
Get() {
return std::get<std::vector<NumT>>(
registers_); }
367 template<
typename NumT>
368 std::vector<NumT>
const&
Get()
const {
return std::get<std::vector<NumT>>(
registers_); }
373 mutable std::tuple< std::vector<real_dbl>, std::vector<complex_dbl>,
388 template <
typename Archive>
389 void serialize(Archive& ar,
const unsigned ) {
390 ar & std::get<std::vector<real_dbl>>(
registers_);
391 ar & std::get<std::vector<complex_dbl>>(
registers_);
392 ar & std::get<std::vector<real_mp>>(
registers_);
393 ar & std::get<std::vector<complex_mp>>(
registers_);
417 using Nd = std::shared_ptr<const node::Node>;
431 inline unsigned NumFunctions()
const{
return static_cast<unsigned>(number_of_.Functions);}
433 inline unsigned NumVariables()
const{
return static_cast<unsigned>(number_of_.Variables);}
435 inline size_t NumSlots()
const {
return num_slots_; }
459 template<
typename NumT>
471 void AddInstruction(
Operation binary_op,
size_t in_loc1,
size_t in_loc2,
size_t out_loc);
480 void AddInstruction(
Operation unary_op,
size_t in_loc,
size_t out_loc);
489 void PartitionInstructions();
494 void ComputeSlotNumTypes();
500 void SpecializeInstructions();
503 bool has_path_variable_ =
false;
509 std::vector<IntT> integers_;
511 std::vector<size_t> instructions_;
512 std::vector<ConstantRecipe> constant_recipes_;
521 size_t first_live_instruction_ = 0;
523 size_t num_slots_ = 0;
528 std::vector<NumType> slot_numtype_;
534 template <
typename Archive>
535 void serialize(Archive& ar,
const unsigned ) {
536 ar & has_path_variable_;
538 ar & output_locations_;
539 ar & input_locations_;
542 ar & constant_recipes_;
543 ar & first_live_instruction_;
563 std::shared_ptr<const SLPProgram>
InternProgram(std::shared_ptr<const SLPProgram>
const& candidate);
592 using Nd = std::shared_ptr<const node::Node>;
606 template<
typename Derived>
607 void Eval(Eigen::MatrixBase<Derived>
const& variable_values)
const
609 using NumT =
typename Derived::Scalar;
611 program_->Eval<NumT>(memory_);
626 template<
typename Derived,
typename ComplexT>
627 void Eval(Eigen::MatrixBase<Derived>
const& variable_values, ComplexT
const& time)
const
629 using NumT =
typename Derived::Scalar;
630 static_assert(std::is_same<NumT, ComplexT>::value,
"scalar types must be the same");
635 program_->Eval<NumT>(memory_);
642 template <
typename T>
644 program_->Eval<T>(memory_);
651 template <
typename T>
653 program_->Eval<T>(memory_);
659 template <
typename T>
661 program_->Eval<T>(memory_);
668 std::shared_ptr<const SLPProgram>
Program()
const {
return program_; }
675 for (
auto t : program_->slot_numtype_)
if (t ==
NumType::Real) ++n;
682 template<
typename NumT>
686 return NumT(memory_.template Get<RealT>()[slot]);
687 return memory_.template Get<NumT>()[slot];
693 template<
typename NumT>
695 if (!memory_.is_evaluated_)
696 program_->Eval<NumT>(memory_);
699 for (
size_t ii = 0; ii < program_->number_of_.Functions; ++ii) {
715 template<
typename NumT>
717 if (!memory_.is_evaluated_)
718 program_->Eval<NumT>(memory_);
721 for (
size_t jj =0; jj < program_->number_of_.Variables; ++jj) {
722 for (
size_t ii = 0; ii < program_->number_of_.Functions; ++ii) {
723 result(
static_cast<Eigen::Index
>(ii),
static_cast<Eigen::Index
>(jj)) =
ReadSlotAsComplex<NumT>(ii+jj*program_->number_of_.Functions + program_->output_locations_.Jacobian);
739 template<
typename NumT>
741 if (!memory_.is_evaluated_)
742 program_->Eval<NumT>(memory_);
745 for (
size_t ii = 0; ii < program_->number_of_.Functions; ++ii) {
756 template<
typename NumT>
768 template<
typename NumT>
780 template<
typename NumT>
789 inline unsigned NumFunctions()
const{
return program_->NumFunctions();}
792 inline unsigned NumVariables()
const{
return program_->NumVariables();}
813 return memory_.precision_;
833 template<
typename Derived>
836 using NumT =
typename Derived::Scalar;
837 if constexpr (!std::is_same<NumT,complex_dbl>::value)
839 if (variable_values.size() > 0 &&
Precision(variable_values)!=memory_.precision_)
850 return program_->has_path_variable_;
866 template<
typename Derived>
868 using NumT =
typename Derived::Scalar;
890 auto& memory = memory_.Get<NumT>();
892 for (
size_t ii = 0; ii < program_->number_of_.Variables; ++ii) {
894 memory[ii + program_->input_locations_.Variables] = variable_values(
static_cast<Eigen::Index
>(ii));
896 memory_.is_evaluated_ =
false;
907 template<
typename ComplexT>
914 if constexpr (!std::is_same<ComplexT,complex_dbl>::value)
916 if (
Precision(time) > memory_.precision_)
921 throw std::runtime_error(
"calling Eval with path variable, but this StraightLineProgram doesn't have one.");
924 auto& memory = memory_.Get<ComplexT>();
926 memory[program_->input_locations_.Time] = time;
929 if constexpr (!std::is_same<ComplexT,complex_dbl>::value)
930 Precision(memory[program_->input_locations_.Time], memory_.precision_);
931 memory_.is_evaluated_ =
false;
948 template<
typename NumT>
949 void CopyNumbersIntoMemory()
const;
952 std::shared_ptr<const SLPProgram> program_;
964 template <
typename Archive>
965 void save(Archive& ar,
const unsigned )
const {
971 template <
typename Archive>
972 void load(Archive& ar,
const unsigned ) {
973 auto prog = std::make_shared<SLPProgram>();
977 program_ =
InternProgram(std::shared_ptr<const SLPProgram>(std::move(prog)));
981 BOOST_SERIALIZATION_SPLIT_MEMBER()
995 public Visitor<node::Variable>,
998 public Visitor<node::Rational>,
999 public Visitor<node::NamedExpression>,
1000 public Visitor<node::Differential>,
1003 public Visitor<node::SumOperator>,
1004 public Visitor<node::MultOperator>,
1005 public Visitor<node::IntegerPowerOperator>,
1006 public Visitor<node::PowerOperator>,
1007 public Visitor<node::ExpOperator>,
1008 public Visitor<node::LogOperator>,
1009 public Visitor<node::NegateOperator>,
1010 public Visitor<node::SqrtOperator>,
1013 public Visitor<node::SinOperator>,
1014 public Visitor<node::ArcSinOperator>,
1015 public Visitor<node::CosOperator>,
1016 public Visitor<node::ArcCosOperator>,
1017 public Visitor<node::TanOperator>,
1018 public Visitor<node::ArcTanOperator>,
1020 public Visitor<node::special_number::Pi>,
1021 public Visitor<node::special_number::E>
1034 using Nd = std::shared_ptr<const node::Node>;
1046 template <
typename SourceT>
1102 size_t EmitBinary(
Operation op,
size_t a,
size_t b);
1104 size_t EmitUnary(
Operation op,
size_t a);
1111 size_t next_available_complex_ = 0;
1112 size_t next_available_int_ = 0;
1116 std::map<Nd, size_t> locations_encountered_nodes_;
1117 std::map<IntT, size_t> locations_integers_;
1122 std::map<std::tuple<Operation,size_t,size_t>,
size_t> vn_binary_;
1123 std::map<std::pair<Operation,size_t>,
size_t> vn_unary_;
Compiles a System (or polynomial block) into a StraightLineProgram by visiting its function-tree node...
Definition straight_line_program.hpp:1032
SLP Compile(SourceT const &source)
Compile a source (a System or polynomial block) into a StraightLineProgram.
The per-thread mutable working state of a straight-line program evaluation: the register file (one ba...
Definition straight_line_program.hpp:360
std::vector< NumT > const & Get() const
Get a const reference to the register bank for number type NumT.
Definition straight_line_program.hpp:368
unsigned precision_
The current working number of digits.
Definition straight_line_program.hpp:376
std::vector< NumT > & Get()
Get a mutable reference to the register bank for number type NumT.
Definition straight_line_program.hpp:364
unsigned frozen_valid_mp_precision_
Precision at which the frozen prologue's mp results are valid (0 = none).
Definition straight_line_program.hpp:383
bool frozen_valid_dbl_
Whether the frozen prologue's double results in memory are valid.
Definition straight_line_program.hpp:382
bool is_evaluated_
Whether the program has been evaluated against this memory.
Definition straight_line_program.hpp:377
std::tuple< std::vector< real_dbl >, std::vector< complex_dbl >, std::vector< real_mp >, std::vector< complex_mp > > registers_
The register file (ADR-0034): one bank per (precision, NumType).
Definition straight_line_program.hpp:374
friend class boost::serialization::access
Definition straight_line_program.hpp:385
The immutable compiled straight-line program (ADR-0027): the instruction tape, the constant recipe (t...
Definition straight_line_program.hpp:411
unsigned NumFunctions() const
Get the number of functions in the program.
Definition straight_line_program.hpp:431
friend std::ostream & operator<<(std::ostream &out, const StraightLineProgram &s)
size_t FirstLiveInstructionOffset() const
Get the word offset into the tape where the live (post-frozen-prologue) segment begins.
Definition straight_line_program.hpp:437
void Eval(SLPMemory &memory) const
loops through the instructions in the tape and evaluates each operation against the given memory.
unsigned NumVariables() const
Get the number of variables in the program.
Definition straight_line_program.hpp:433
bool SameContent(SLPProgram const &other) const
Exact content equality over every field ContentHash folds; disambiguates hash collisions in the progr...
std::size_t ContentHash() const
In-process structural hash of the full immutable program content: the (specialized) instruction tape,...
friend class boost::serialization::access
Definition straight_line_program.hpp:531
int IntT
The integer type used for the program's integer bank.
Definition straight_line_program.hpp:420
friend class StraightLineProgram
Definition straight_line_program.hpp:413
size_t NumSlots() const
Get the total number of memory slots (per register bank) the program needs.
Definition straight_line_program.hpp:435
bool HavePathVariable() const
Query whether the program has a path variable.
Definition straight_line_program.hpp:429
static bool tiers_enabled_
ADR-0034 A/B switch: when false, leave every slot Complex (pre-tier all-complex eval).
Definition straight_line_program.hpp:426
An implementation of straight-line programs, implemented with strong inspiration from Bertini1's impl...
Definition straight_line_program.hpp:587
StraightLineProgram(System const &sys)
The constructor – how to make a SLP from a System.
int IntT
The integer type used for the program's integer bank.
Definition straight_line_program.hpp:939
void EvalFunctions() const
Evaluate the program's functions (currently a synonym for the full Eval).
Definition straight_line_program.hpp:643
unsigned NumFunctions() const
Get the number of functions in the program.
Definition straight_line_program.hpp:789
size_t FirstLiveInstructionOffset() const
Word offset into the instruction tape where the live segment begins (== total word length of the froz...
Definition straight_line_program.hpp:802
friend std::ostream & operator<<(std::ostream &out, const StraightLineProgram &s)
void GetJacobianInPlace(Eigen::Ref< Mat< NumT > > result) const
retrieves the computed values of jacobians
Definition straight_line_program.hpp:716
void GetTimeDerivInPlace(Eigen::Ref< Vec< NumT > > result) const
copies the values of the time derivatives into your given vector
Definition straight_line_program.hpp:740
Vec< NumT > GetTimeDeriv() const
creates the Vec<NumT> to be used in the overloaded function
Definition straight_line_program.hpp:781
void EvalJacobian() const
Evaluate the program's Jacobian (currently a synonym for the full Eval).
Definition straight_line_program.hpp:652
NumT ReadSlotAsComplex(size_t slot) const
Read a slot's value as a complex NumT, pulling from its real or complex bank per its NumType.
Definition straight_line_program.hpp:683
void SetVariableValues(Eigen::MatrixBase< Derived > const &variable_values) const
Copy the values of the variables from the passed in vector to memory.
Definition straight_line_program.hpp:867
size_t NumMemorySlots() const
Number of memory slots: one per distinct value the program holds (inputs, constants,...
Definition straight_line_program.hpp:797
unsigned precision() const
Get the current precision of the SLP.
Definition straight_line_program.hpp:811
void Eval(Eigen::MatrixBase< Derived > const &variable_values) const
Evaluate the program at the given variable values (no path variable).
Definition straight_line_program.hpp:607
bool HavePathVariable() const
Does this SLP have a path variable?
Definition straight_line_program.hpp:849
unsigned NumVariables() const
Get the number of variables in the program.
Definition straight_line_program.hpp:792
void precision(unsigned new_precision) const
change the precision of the SLP.
void SetPathVariable(ComplexT const &time) const
Copy the current time value to memory.
Definition straight_line_program.hpp:908
Mat< NumT > GetJacobian() const
creates the Vec<NumT> to be used in the overloaded function
Definition straight_line_program.hpp:769
void GetFuncValsInPlace(Eigen::Ref< Vec< NumT > > result) const
Copy the computed function values into the provided vector (does not resize it).
Definition straight_line_program.hpp:694
void Eval(Eigen::MatrixBase< Derived > const &variable_values, ComplexT const &time) const
copies the variable values into the Matrix base and the path variables into the complex type time
Definition straight_line_program.hpp:627
friend class boost::serialization::access
Definition straight_line_program.hpp:957
Vec< NumT > GetFuncVals() const
creates the Vec<NumT> to be used in the overloaded function
Definition straight_line_program.hpp:757
void SyncPrecision(Eigen::MatrixBase< Derived > const &variable_values) const
Materialize this program's memory at the precision of the point being evaluated.
Definition straight_line_program.hpp:834
std::shared_ptr< const SLPProgram > Program() const
The immutable compiled program this facade runs.
Definition straight_line_program.hpp:668
size_t NumRealSlots() const
Number of slots the compiler inferred as NumType::Real (ADR-0034).
Definition straight_line_program.hpp:673
void EvalTimeDeriv() const
Evaluate the program's time derivative (currently a synonym for the full Eval).
Definition straight_line_program.hpp:660
StraightLineProgram()
Definition straight_line_program.hpp:601
The fundamental polynomial system class for Bertini2.
Definition system.hpp:106
A strawman class for implementing the visitor pattern.
Definition visitor.hpp:42
The first non-trivial visitor class.
Definition visitor.hpp:58
virtual ReturnType Visit(node::Variable const &)=0
Provides the arc cosine Operator.
Definition trig.hpp:264
Provides the inverse sine Operator.
Definition trig.hpp:139
Provides the inverse tangent Operator.
Definition trig.hpp:391
A complex-number literal node in an expression tree.
Definition number.hpp:254
Provides the cosine Operator.
Definition trig.hpp:202
Provides the differential type for differentiation of expression trees.
Definition differential.hpp:52
represents the exponential function
Definition arithmetic.hpp:914
This class represents the exponentiation Operator.
Definition arithmetic.hpp:709
Signed real Integer storage in an expression tree.
Definition number.hpp:143
represents the natural logarithm function
Definition arithmetic.hpp:971
Multiplication and division Operator.
Definition arithmetic.hpp:379
A user-named expression — the surviving, immutable entry point into a subtree.
Definition named_expression.hpp:50
The negation Operator.
Definition arithmetic.hpp:271
Operator for power functions with arbitrary expressions in the exponent and base.
Definition arithmetic.hpp:559
The Rational number type for Bertini2 expression trees.
Definition number.hpp:379
Provides the sine Operator.
Definition trig.hpp:80
Represents the square root Operator.
Definition arithmetic.hpp:847
Represents summation and difference Operator.
Definition arithmetic.hpp:70
Provides the tangent Operator.
Definition trig.hpp:332
Represents variable leaves in the function tree.
Definition variable.hpp:48
The number .
Definition special_number.hpp:115
The number .
Definition special_number.hpp:55
Bertini extensions of the Eigen linear algebra library.
Forward declarations for types in the node:: namespace.
The main multiprecision complex number type.
Extensions to the Boost.Multiprecision library.
Definition algorithm_builder.hpp:36
std::string OpcodeToString(Operation op)
Get a human-readable name for an opcode.
constexpr bool IsBinary(Operation op)
Query whether an operation takes two operands.
Definition straight_line_program.hpp:200
Eigen::Matrix< NumT, Eigen::Dynamic, 1 > Vec
A dynamically-sized column vector of NumT.
Definition eigen_extensions.hpp:296
bool SLPValueNumbering()
Whether the SLP compiler value-numbers (instruction-level CSE) while emitting the tape: an identical ...
constexpr size_t kOutReal
High bit: result slot is NumType::Real.
Definition straight_line_program.hpp:225
boost::multiprecision::number< boost::multiprecision::backends::gmp_int, boost::multiprecision::et_on > mpz_int
The arbitrary-precision integer type.
Definition mpfr_extensions.hpp:54
constexpr size_t kArg0Real
High bit: first operand slot is NumType::Real.
Definition straight_line_program.hpp:223
constexpr bool IsUnary(Operation op)
Query whether an operation takes a single operand.
Definition straight_line_program.hpp:194
Eigen::Matrix< NumT, Eigen::Dynamic, Eigen::Dynamic > Mat
A dynamically-sized matrix of NumT.
Definition eigen_extensions.hpp:298
void SetSLPValueNumbering(bool on)
Set whether the SLP compiler value-numbers while emitting the tape.
constexpr size_t kOpcodeMask
Mask recovering the base opcode from an instruction word.
Definition straight_line_program.hpp:222
bmp::number< mpc_complex_backend< 0 >, bmp::et_on > complex_mp
The arbitrary-precision complex number type.
Definition mpfr_complex.hpp:58
constexpr size_t kArg1Real
High bit: second operand slot is Real (binary, not IntPower).
Definition straight_line_program.hpp:224
std::shared_ptr< const SLPProgram > InternProgram(std::shared_ptr< const SLPProgram > const &candidate)
Hash-cons a freshly-compiled program: return an existing content-equal SLPProgram if one is live,...
const int UnaryOperations
Bit-mask of the one-operand operations.
Definition straight_line_program.hpp:191
boost::multiprecision::number< boost::multiprecision::backends::gmp_rational, boost::multiprecision::et_on > mpq_rational
The exact rational number type.
Definition mpfr_extensions.hpp:55
unsigned Precision(Eigen::MatrixBase< Derived > const &v)
Get the precision of an Eigen object.
Definition eigen_extensions.hpp:339
NumType
The numeric type a memory slot holds, orthogonal to working precision (ADR-0034).
Definition straight_line_program.hpp:165
@ Complex
Definition straight_line_program.hpp:165
@ Real
Definition straight_line_program.hpp:165
Operation
The opcodes for the operations a straight-line program instruction can perform.
Definition straight_line_program.hpp:169
@ Acos
Definition straight_line_program.hpp:183
@ Asin
Definition straight_line_program.hpp:182
@ Atan
Definition straight_line_program.hpp:184
@ Exp
Definition straight_line_program.hpp:175
@ Multiply
Definition straight_line_program.hpp:172
@ Cos
Definition straight_line_program.hpp:180
@ IntPower
Definition straight_line_program.hpp:186
@ Subtract
Definition straight_line_program.hpp:171
@ Power
Definition straight_line_program.hpp:174
@ Sqrt
Definition straight_line_program.hpp:178
@ Assign
Definition straight_line_program.hpp:185
@ Log
Definition straight_line_program.hpp:176
@ Add
Definition straight_line_program.hpp:170
@ Tan
Definition straight_line_program.hpp:181
@ Negate
Definition straight_line_program.hpp:177
@ Divide
Definition straight_line_program.hpp:173
@ Sin
Definition straight_line_program.hpp:179
const int TrigOperations
Bit-mask of the trigonometric operations.
Definition straight_line_program.hpp:190
const int BinaryOperations
Bit-mask of the two-operand operations.
Definition straight_line_program.hpp:189
An exact, node-independent description of a constant baked into the program: enough to (re)produce th...
Definition straight_line_program.hpp:306
mpq_rational rat_real
Kind::Rational real part (exact).
Definition straight_line_program.hpp:312
bool IsReal() const
Whether this constant is real-valued: Integer/Pi/E always; a Rational/Complex literal iff its imagina...
Definition straight_line_program.hpp:326
size_t slot
where this constant lives in the register file
Definition straight_line_program.hpp:315
mpz_int int_value
Kind::Integer (exact).
Definition straight_line_program.hpp:311
Kind
Which kind of constant this recipe produces.
Definition straight_line_program.hpp:308
@ Complex
Definition straight_line_program.hpp:308
@ Pi
Definition straight_line_program.hpp:308
@ Rational
Definition straight_line_program.hpp:308
@ E
Definition straight_line_program.hpp:308
@ Integer
Definition straight_line_program.hpp:308
mpq_rational rat_imag
Kind::Rational imaginary part (exact).
Definition straight_line_program.hpp:313
Kind kind
Which kind of constant this is.
Definition straight_line_program.hpp:310
RealT ProduceReal() const
Produce just the REAL value (for a slot inferred NumType::Real). Only valid when IsReal().
friend class boost::serialization::access
Definition straight_line_program.hpp:335
NumT Produce() const
Produce the constant's value at the ambient working precision (ThreadPrecision), matching the corresp...
complex_mp float_value
Kind::Complex (authored-precision literal; also a fixed variable's value).
Definition straight_line_program.hpp:314
Numeric traits for a bertini number type: digit counts, conversions, and companion types.
Definition num_traits.hpp:57
A struct encapsulating the numbers of things appearing in the SLP.
Definition straight_line_program.hpp:275
size_t Functions
The number of functions in the system.
Definition straight_line_program.hpp:276
size_t Jacobian
The number of Jacobian entries.
Definition straight_line_program.hpp:278
friend class boost::serialization::access
Definition straight_line_program.hpp:281
size_t Variables
The number of variables in the system.
Definition straight_line_program.hpp:277
size_t TimeDeriv
The number of time-derivative entries.
Definition straight_line_program.hpp:279
A struct encapsulating the starting locations of outputs in the SLP's memory layout.
Definition straight_line_program.hpp:233
size_t Functions
Memory offset of the function-value outputs.
Definition straight_line_program.hpp:234
size_t TimeDeriv
Memory offset of the time-derivative outputs.
Definition straight_line_program.hpp:236
size_t Jacobian
Memory offset of the Jacobian outputs.
Definition straight_line_program.hpp:235
friend class boost::serialization::access
Definition straight_line_program.hpp:238
Contains the visitor base types.