Graph Framework
Loading...
Searching...
No Matches
node.hpp
Go to the documentation of this file.
1//------------------------------------------------------------------------------
6//------------------------------------------------------------------------------
7//------------------------------------------------------------------------------
346//------------------------------------------------------------------------------
347#ifndef node_h
348#define node_h
349
350#include <iostream>
351#include <string>
352#include <memory>
353#include <iomanip>
354#include <functional>
355#include <type_traits>
356
357#include "backend.hpp"
358
360namespace graph {
361//******************************************************************************
362// Base leaf node.
363//******************************************************************************
364//------------------------------------------------------------------------------
369//------------------------------------------------------------------------------
370 template<jit::float_scalar T, bool SAFE_MATH=false>
371 class leaf_node : public std::enable_shared_from_this<leaf_node<T, SAFE_MATH>> {
372 protected:
374 const size_t hash;
376 const size_t complexity;
378 std::unordered_map<size_t, std::shared_ptr<leaf_node<T, SAFE_MATH>>> df_cache;
380 const bool contains_pseudo;
381
382 public:
383//------------------------------------------------------------------------------
389//------------------------------------------------------------------------------
390 leaf_node(const std::string s,
391 const size_t count,
392 const bool pseudo) :
393 hash(std::hash<std::string>{} (s)),
395
396//------------------------------------------------------------------------------
398//------------------------------------------------------------------------------
399 virtual ~leaf_node() {}
400
401//------------------------------------------------------------------------------
405//------------------------------------------------------------------------------
407
408//------------------------------------------------------------------------------
414//------------------------------------------------------------------------------
415 virtual std::shared_ptr<leaf_node<T, SAFE_MATH>> reduce() {
416 return this->shared_from_this();
417 }
418
419//------------------------------------------------------------------------------
424//------------------------------------------------------------------------------
425 virtual std::shared_ptr<leaf_node<T, SAFE_MATH>>
426 df(std::shared_ptr<leaf_node<T, SAFE_MATH>> x) {
427 return std::shared_ptr<leaf_node<T, SAFE_MATH>> ();
428 };
429
430//------------------------------------------------------------------------------
444//------------------------------------------------------------------------------
445 virtual void compile_preamble(std::ostringstream &stream,
446 jit::register_map &registers,
451 jit::preamble_map &pre_funcs,
452 int &avail_const_mem) {
453#ifdef SHOW_USE_COUNT
454 if (usage.find(this) == usage.end()) {
455 usage[this] = 1;
456 } else {
457 ++usage[this];
458 }
459#endif
460 }
461
462//------------------------------------------------------------------------------
470//------------------------------------------------------------------------------
471 virtual std::shared_ptr<leaf_node<T, SAFE_MATH>>
472 compile(std::ostringstream &stream,
473 jit::register_map &registers,
475 const jit::register_usage &usage) = 0;
476
477//------------------------------------------------------------------------------
482//------------------------------------------------------------------------------
483 virtual bool is_match(std::shared_ptr<leaf_node<T, SAFE_MATH>> x) {
484 return this == x.get();
485 }
486
487//------------------------------------------------------------------------------
492//------------------------------------------------------------------------------
494 return this->get_power_base()->is_match(x->get_power_base());
495 }
496
497//------------------------------------------------------------------------------
501//------------------------------------------------------------------------------
502 virtual void set(const T d) {}
503
504//------------------------------------------------------------------------------
509//------------------------------------------------------------------------------
510 virtual void set(const size_t index,
511 const T d) {}
512
513//------------------------------------------------------------------------------
517//------------------------------------------------------------------------------
518 virtual void set(const std::vector<T> &d) {}
519
520//------------------------------------------------------------------------------
524//------------------------------------------------------------------------------
525 virtual void set(const backend::buffer<T> &d) {}
526
527//------------------------------------------------------------------------------
529//------------------------------------------------------------------------------
530 virtual void to_latex() const {};
531
532//------------------------------------------------------------------------------
538//------------------------------------------------------------------------------
539 virtual std::shared_ptr<leaf_node<T, SAFE_MATH>> to_vizgraph(std::stringstream &stream,
540 jit::register_map &registers) = 0;
541
542//------------------------------------------------------------------------------
546//------------------------------------------------------------------------------
547 virtual bool is_constant() const {
548 return false;
549 }
550
551//------------------------------------------------------------------------------
555//------------------------------------------------------------------------------
556 virtual bool has_constant_zero() const {
557 return false;
558 }
559
560//------------------------------------------------------------------------------
564//------------------------------------------------------------------------------
565 bool is_normal() {
566 return this->evaluate().is_normal();
567 }
568
569//------------------------------------------------------------------------------
573//------------------------------------------------------------------------------
574 virtual bool is_all_variables() const {
575 return false;
576 }
577
578//------------------------------------------------------------------------------
584//------------------------------------------------------------------------------
585 virtual bool is_power_like() const {
586 return false;
587 }
588
589//------------------------------------------------------------------------------
595//------------------------------------------------------------------------------
596 virtual std::shared_ptr<leaf_node<T, SAFE_MATH>> get_power_base() {
597 return this->shared_from_this();
598 }
599
600//------------------------------------------------------------------------------
607//------------------------------------------------------------------------------
608 virtual std::shared_ptr<leaf_node<T, SAFE_MATH>> get_power_exponent() const = 0;
609
610//------------------------------------------------------------------------------
614//------------------------------------------------------------------------------
615 size_t get_hash() const {
616 return hash;
617 }
618
619//------------------------------------------------------------------------------
623//------------------------------------------------------------------------------
624 size_t get_complexity() const {
625 return complexity;
626 }
627
628//------------------------------------------------------------------------------
632//------------------------------------------------------------------------------
633 virtual bool has_pseudo() const {
634 return contains_pseudo;
635 }
636
637//------------------------------------------------------------------------------
641//------------------------------------------------------------------------------
642 virtual std::shared_ptr<leaf_node<T, SAFE_MATH>> remove_pseudo() {
643 return this->shared_from_this();
644 }
645
646//------------------------------------------------------------------------------
652//------------------------------------------------------------------------------
653 virtual void endline(std::ostringstream &stream,
655 const char end=';')
656#ifndef SHOW_USE_COUNT
657 const
658#endif
659 {
660 stream << end
661#ifdef SHOW_USE_COUNT
662 << " // used " << usage.at(this)
663#endif
664 << std::endl;
665 }
666
667// Create one struct that holds both caches: for constructed nodes and for the
668// backend buffers
669//------------------------------------------------------------------------------
674//------------------------------------------------------------------------------
675 struct caches_t {
677 std::unordered_map<size_t, std::shared_ptr<leaf_node<T, SAFE_MATH>>> nodes;
679 std::unordered_map<size_t, backend::buffer<T>> backends;
680 };
681
683 inline static thread_local caches_t caches;
684
686 typedef T base;
687 };
688
690 template<jit::float_scalar T, bool SAFE_MATH=false>
691 using shared_leaf = std::shared_ptr<leaf_node<T, SAFE_MATH>>;
692//------------------------------------------------------------------------------
699//------------------------------------------------------------------------------
700 template<jit::float_scalar T, bool SAFE_MATH=false>
705 template<jit::float_scalar T, bool SAFE_MATH=false>
706 using output_nodes = std::vector<shared_leaf<T, SAFE_MATH>>;
707
709 template<jit::float_scalar T, bool SAFE_MATH=false>
712 template<jit::float_scalar T, bool SAFE_MATH=false>
713 constexpr shared_leaf<T, SAFE_MATH> one();
714
715//------------------------------------------------------------------------------
719//------------------------------------------------------------------------------
720 template<jit::float_scalar T, bool SAFE_MATH=false>
722 std::stringstream stream;
723 jit::register_map registers;
725
726 stream << "graph \"\" {" << std::endl;
727 stream << " node [fontname = \"Helvetica\", ordering = out]" << std::endl << std::endl;
728 node->to_vizgraph(stream, registers);
729 stream << "}" << std::endl;
730
731 std::cout << stream.str() << std::endl;
732 }
733
734//******************************************************************************
736//******************************************************************************
737//------------------------------------------------------------------------------
742//------------------------------------------------------------------------------
743 template<jit::float_scalar T, bool SAFE_MATH=false>
744 class index_node final : public leaf_node<T, SAFE_MATH> {
745 private:
746//------------------------------------------------------------------------------
750//------------------------------------------------------------------------------
751 static std::string to_string() {
752 return "i";
753 }
754
755 public:
756//------------------------------------------------------------------------------
758//------------------------------------------------------------------------------
760 leaf_node<T, SAFE_MATH> (index_node::to_string(), 1, false) {}
761
762//------------------------------------------------------------------------------
766//------------------------------------------------------------------------------
768 return backend::buffer<T> ();
769 }
770
771//------------------------------------------------------------------------------
776//------------------------------------------------------------------------------
780
781//------------------------------------------------------------------------------
789//------------------------------------------------------------------------------
790 virtual std::shared_ptr<leaf_node<T, SAFE_MATH>>
791 compile(std::ostringstream &stream,
792 jit::register_map &registers,
794 const jit::register_usage &usage) {
795 if (registers.find(this) == registers.end()) {
796 registers[this] = jit::to_string('i', this);
797 stream << " const ";
798 if constexpr (jit::use_cuda()) {
799 stream << "int " << registers[this] << " = index";
800 } else if constexpr (jit::use_metal<T> ()) {
801 stream << "uint " << registers[this] << " = index";
802 } else {
803 stream << "size_t " << registers[this] << " = i";
804 }
805 this->endline(stream, usage);
806 }
807
808 return this->shared_from_this();
809 }
810
811//------------------------------------------------------------------------------
813//------------------------------------------------------------------------------
814 virtual void to_latex() const {
815 std::cout << "i";
816 };
817
818//------------------------------------------------------------------------------
824//------------------------------------------------------------------------------
825 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
826 jit::register_map &registers) {
827 if (registers.find(this) == registers.end()) {
828 const std::string name = jit::to_string('i', this);
829 registers[this] = name;
830 stream << " " << name
831 << " [label = \"i\", shape = box, style = \"rounded,filled\", fillcolor = black, fontcolor = white];" << std::endl;
832 }
833
834 return this->shared_from_this();
835 }
836
837//------------------------------------------------------------------------------
841//------------------------------------------------------------------------------
843 return one<T, SAFE_MATH> ();
844 }
845 };
846
847//------------------------------------------------------------------------------
854//------------------------------------------------------------------------------
855 template<jit::float_scalar T, bool SAFE_MATH=false>
857 auto temp = std::make_shared<index_node<T, SAFE_MATH>> ();
858// Test for hash collisions.
859 for (size_t i = temp->get_hash(); i < std::numeric_limits<size_t>::max(); i++) {
860 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
863 return temp;
864 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
866 }
867 }
868#if defined(__clang__) || defined(__GNUC__)
870#else
871 assert(false && "Should never reach.");
872#endif
873 }
874
876 template<jit::float_scalar T, bool SAFE_MATH=false>
877 using shared_index = std::shared_ptr<index_node<T, SAFE_MATH>>;
878
879//------------------------------------------------------------------------------
887//------------------------------------------------------------------------------
888 template<jit::float_scalar T, bool SAFE_MATH=false>
890 return std::dynamic_pointer_cast<index_node<T, SAFE_MATH>> (x);
891 }
892
893//******************************************************************************
894// Constant node.
895//******************************************************************************
896//------------------------------------------------------------------------------
901//------------------------------------------------------------------------------
902 template<jit::float_scalar T, bool SAFE_MATH=false>
903 class constant_node final : public leaf_node<T, SAFE_MATH> {
904 private:
905//------------------------------------------------------------------------------
910//------------------------------------------------------------------------------
911 static std::string to_string(const T d) {
912 return jit::format_to_string<T> (d);
913 }
914
916 const backend::buffer<T> data;
917
918 public:
919//------------------------------------------------------------------------------
923//------------------------------------------------------------------------------
925 leaf_node<T, SAFE_MATH> (constant_node::to_string(d.at(0)), 1, false), data(d) {
926 if constexpr (SAFE_MATH) {
927 assert(d.is_normal() && "Denormal encountered");
928 }
929 assert(d.size() == 1 && "Constants need to be scalar functions.");
930 }
931
932//------------------------------------------------------------------------------
936//------------------------------------------------------------------------------
938 return data;
939 }
940
941//------------------------------------------------------------------------------
946//------------------------------------------------------------------------------
950
951//------------------------------------------------------------------------------
959//------------------------------------------------------------------------------
961 compile(std::ostringstream &stream,
962 jit::register_map &registers,
964 const jit::register_usage &usage) {
965 if (registers.find(this) == registers.end()) {
966#ifdef USE_CONSTANT_CACHE
967 registers[this] = jit::to_string('r', this);
968 stream << " const ";
969 jit::add_type<T> (stream);
970 const T temp = this->evaluate().at(0);
971
972 stream << " " << registers[this] << " = ";
973 if constexpr (jit::complex_scalar<T>) {
974 jit::add_type<T> (stream);
975 }
976 stream << temp;
977 this->endline(stream, usage);
978#else
979 if constexpr (jit::complex_scalar<T>) {
980 registers[this] = jit::get_type_string<T> () + "("
981 + jit::format_to_string(this->evaluate().at(0))
982 + ")";
983 } else {
984 registers[this] = "(" + jit::get_type_string<T> () + ")"
985 + jit::format_to_string(this->evaluate().at(0));
986 }
987#endif
988 }
989
990 return this->shared_from_this();
991 }
992
993//------------------------------------------------------------------------------
998//------------------------------------------------------------------------------
1000 if (this == x.get()) {
1001 return true;
1002 }
1003
1004 auto x_cast = constant_cast(x);
1005 if (x_cast.get()) {
1006 return this->evaluate() == x_cast->evaluate();
1007 }
1008
1009 return false;
1010 }
1011
1012//------------------------------------------------------------------------------
1014//------------------------------------------------------------------------------
1015 bool is(const T d) {
1016 return data.size() == 1 && data.at(0) == d;
1017 }
1018
1019//------------------------------------------------------------------------------
1021//------------------------------------------------------------------------------
1022 bool is_integer() {
1023 const auto temp = this->evaluate().at(0);
1024 return std::imag(temp) == 0 &&
1025 fmod(std::real(temp), 1.0) == 0.0;
1026 }
1027
1028//------------------------------------------------------------------------------
1030//------------------------------------------------------------------------------
1031 virtual void to_latex() const {
1032 std::cout << data.at(0);
1033 }
1034
1035//------------------------------------------------------------------------------
1041//------------------------------------------------------------------------------
1042 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
1043 jit::register_map &registers) {
1044 if (registers.find(this) == registers.end()) {
1045 const std::string name = jit::to_string('r', this);
1046 registers[this] = name;
1047 stream << " " << name
1048 << " [label = \"" << this->evaluate().at(0)
1049 << "\", shape = box, style = \"rounded,filled\", fillcolor = black, fontcolor = white];" << std::endl;
1050 }
1051
1052 return this->shared_from_this();
1053 }
1054
1055//------------------------------------------------------------------------------
1059//------------------------------------------------------------------------------
1060 virtual bool is_constant() const {
1061 return true;
1062 }
1063
1064//------------------------------------------------------------------------------
1068//------------------------------------------------------------------------------
1069 virtual bool has_constant_zero() const {
1070 return data.has_zero();
1071 }
1072
1073//------------------------------------------------------------------------------
1077//------------------------------------------------------------------------------
1078 virtual bool is_power_like() const {
1079 return true;
1080 }
1081
1082//------------------------------------------------------------------------------
1086//------------------------------------------------------------------------------
1088 return this->shared_from_this();
1089 }
1090
1091//------------------------------------------------------------------------------
1095//------------------------------------------------------------------------------
1097 return one<T, SAFE_MATH> ();
1098 }
1099 };
1100
1101//------------------------------------------------------------------------------
1109//------------------------------------------------------------------------------
1110 template<jit::float_scalar T, bool SAFE_MATH=false>
1112 auto temp = std::make_shared<constant_node<T, SAFE_MATH>> (d);
1113// Test for hash collisions.
1114 for (size_t i = temp->get_hash(); i < std::numeric_limits<size_t>::max(); i++) {
1115 if (leaf_node<T, SAFE_MATH>::caches.nodes.find(i) ==
1116 leaf_node<T, SAFE_MATH>::caches.nodes.end()) {
1118 return temp;
1119 } else if (temp->is_match(leaf_node<T, SAFE_MATH>::caches.nodes[i])) {
1120 return leaf_node<T, SAFE_MATH>::caches.nodes[i];
1121 }
1122 }
1123#if defined(__clang__) || defined(__GNUC__)
1125#else
1126 assert(false && "Should never reach.");
1127#endif
1128 }
1129
1130//------------------------------------------------------------------------------
1138//------------------------------------------------------------------------------
1139 template<jit::float_scalar T, bool SAFE_MATH=false>
1143
1144// Define some common constants.
1145//------------------------------------------------------------------------------
1152//------------------------------------------------------------------------------
1153 template<jit::float_scalar T, bool SAFE_MATH>
1155 return constant<T, SAFE_MATH> (static_cast<T> (0.0));
1156 }
1157
1158//------------------------------------------------------------------------------
1165//------------------------------------------------------------------------------
1166 template<jit::float_scalar T, bool SAFE_MATH>
1168 return constant<T, SAFE_MATH> (static_cast<T> (1.0));
1169 }
1170
1171//------------------------------------------------------------------------------
1178//------------------------------------------------------------------------------
1179 template<jit::float_scalar T, bool SAFE_MATH=false>
1181 return constant<T, SAFE_MATH> (static_cast<T> (-1.0));
1182 }
1183
1185 template<jit::complex_scalar T>
1186 constexpr T i = T(0.0, 1.0);
1187
1189 template<jit::float_scalar T, bool SAFE_MATH=false>
1190 using shared_constant = std::shared_ptr<constant_node<T, SAFE_MATH>>;
1191
1192//------------------------------------------------------------------------------
1200//------------------------------------------------------------------------------
1201 template<jit::float_scalar T, bool SAFE_MATH=false>
1203 return std::dynamic_pointer_cast<constant_node<T, SAFE_MATH>> (x);
1204 }
1205
1206//******************************************************************************
1207// Base straight node.
1208//******************************************************************************
1209//------------------------------------------------------------------------------
1217//------------------------------------------------------------------------------
1218 template<jit::float_scalar T, bool SAFE_MATH=false>
1219 class straight_node : public leaf_node<T, SAFE_MATH> {
1220 protected:
1223
1224 public:
1225//------------------------------------------------------------------------------
1230//------------------------------------------------------------------------------
1232 const std::string s) :
1233 leaf_node<T, SAFE_MATH> (s, a->get_complexity() + 1, a->has_pseudo()),
1234 arg(a) {}
1235
1236//------------------------------------------------------------------------------
1240//------------------------------------------------------------------------------
1242 return arg->evaluate();
1243 }
1244
1245//------------------------------------------------------------------------------
1256//------------------------------------------------------------------------------
1257 virtual void compile_preamble(std::ostringstream &stream,
1258 jit::register_map &registers,
1263 jit::preamble_map &pre_funcs,
1264 int &avail_const_mem) {
1265 if (!visited.contains(this)) {
1266 arg->compile_preamble(stream, registers,
1267 visited, usage,
1269 pre_funcs, avail_const_mem);
1270 visited.insert(this);
1271#ifdef SHOW_USE_COUNT
1272 usage[this] = 1;
1273 } else {
1274 ++usage[this];
1275#endif
1276 }
1277 }
1278
1279//------------------------------------------------------------------------------
1287//------------------------------------------------------------------------------
1289 compile(std::ostringstream &stream,
1290 jit::register_map &registers,
1292 const jit::register_usage &usage) {
1293 return arg->compile(stream, registers, thread_mem, usage);
1294 }
1295
1296//------------------------------------------------------------------------------
1300//------------------------------------------------------------------------------
1302 return arg;
1303 }
1304
1305//------------------------------------------------------------------------------
1309//------------------------------------------------------------------------------
1310 virtual bool is_all_variables() const {
1311 return arg->is_all_variables();
1312 }
1313
1314//------------------------------------------------------------------------------
1318//------------------------------------------------------------------------------
1320 return one<T, SAFE_MATH> ();
1321 }
1322 };
1323
1324//******************************************************************************
1325// Base branch node.
1326//******************************************************************************
1327//------------------------------------------------------------------------------
1335//------------------------------------------------------------------------------
1336 template<jit::float_scalar T, bool SAFE_MATH=false>
1337 class branch_node : public leaf_node<T, SAFE_MATH> {
1338 protected:
1343
1344 public:
1345
1346//------------------------------------------------------------------------------
1352//------------------------------------------------------------------------------
1355 const std::string s) :
1356 leaf_node<T, SAFE_MATH> (s, l->get_complexity() + r->get_complexity() + 1,
1357 l->has_pseudo() || r->has_pseudo()),
1358 left(l), right(r) {}
1359
1360//------------------------------------------------------------------------------
1368//------------------------------------------------------------------------------
1371 const std::string s,
1372 const size_t count,
1373 const bool pseudo) :
1374 leaf_node<T, SAFE_MATH> (s, count, pseudo),
1375 left(l), right(r) {}
1376
1377//------------------------------------------------------------------------------
1388//------------------------------------------------------------------------------
1389 virtual void compile_preamble(std::ostringstream &stream,
1390 jit::register_map &registers,
1395 jit::preamble_map &pre_funcs,
1396 int &avail_const_mem) {
1397 if (!visited.contains(this)) {
1398 left->compile_preamble(stream, registers,
1399 visited, usage,
1401 pre_funcs, avail_const_mem);
1402 right->compile_preamble(stream, registers,
1403 visited, usage,
1405 pre_funcs, avail_const_mem);
1406 visited.insert(this);
1407#ifdef SHOW_USE_COUNT
1408 usage[this] = 1;
1409 } else {
1410 ++usage[this];
1411#endif
1412 }
1413 }
1414
1415//------------------------------------------------------------------------------
1419//------------------------------------------------------------------------------
1421 return left;
1422 }
1423
1424//------------------------------------------------------------------------------
1428//------------------------------------------------------------------------------
1430 return right;
1431 }
1432
1433//------------------------------------------------------------------------------
1437//------------------------------------------------------------------------------
1438 virtual bool is_all_variables() const {
1439 return left->is_all_variables() &&
1440 right->is_all_variables();
1441 }
1442
1443//------------------------------------------------------------------------------
1447//------------------------------------------------------------------------------
1448 virtual std::shared_ptr<leaf_node<T, SAFE_MATH>>
1450 return one<T, SAFE_MATH> ();
1451 }
1452 };
1453
1454//******************************************************************************
1455// Base triple node.
1456//******************************************************************************
1457//------------------------------------------------------------------------------
1465//------------------------------------------------------------------------------
1466 template<jit::float_scalar T, bool SAFE_MATH=false>
1467 class triple_node : public branch_node<T, SAFE_MATH> {
1468 protected:
1471
1472 public:
1473//------------------------------------------------------------------------------
1480//------------------------------------------------------------------------------
1484 const std::string s) :
1485 branch_node<T, SAFE_MATH> (l, r, s,
1486 l->get_complexity() +
1487 m->get_complexity() +
1488 r->get_complexity(),
1489 l->has_pseudo() ||
1490 m->has_pseudo() ||
1491 r->has_pseudo()),
1492 middle(m) {}
1493
1494//------------------------------------------------------------------------------
1505//------------------------------------------------------------------------------
1506 virtual void compile_preamble(std::ostringstream &stream,
1507 jit::register_map &registers,
1512 jit::preamble_map &pre_funcs,
1513 int &avail_const_mem) {
1514 if (!visited.contains(this)) {
1515 this->left->compile_preamble(stream, registers,
1516 visited, usage,
1518 pre_funcs, avail_const_mem);
1519 this->middle->compile_preamble(stream, registers,
1520 visited, usage,
1522 pre_funcs, avail_const_mem);
1523 this->right->compile_preamble(stream, registers,
1524 visited, usage,
1526 pre_funcs, avail_const_mem);
1527 visited.insert(this);
1528#ifdef SHOW_USE_COUNT
1529 usage[this] = 1;
1530 } else {
1531 ++usage[this];
1532#endif
1533 }
1534 }
1535
1536//------------------------------------------------------------------------------
1540//------------------------------------------------------------------------------
1542 return middle;
1543 }
1544
1545//------------------------------------------------------------------------------
1549//------------------------------------------------------------------------------
1550 virtual bool is_all_variables() const {
1551 return this->left->is_all_variables() &&
1552 middle->is_all_variables() &&
1553 this->right->is_all_variables();
1554 }
1555 };
1556
1557//******************************************************************************
1558// Base N arg node.
1559//******************************************************************************
1560//------------------------------------------------------------------------------
1569//------------------------------------------------------------------------------
1570 template<size_t N, jit::float_scalar T, bool SAFE_MATH=false>
1571 class n_branch_node : public leaf_node<T, SAFE_MATH> {
1572 protected:
1574 std::array<shared_leaf<T, SAFE_MATH>, N> branches;
1575
1576//------------------------------------------------------------------------------
1581//------------------------------------------------------------------------------
1583 for (auto &b : branches) {
1584 const bool test = b->has_pseudo();
1585 if (test) {
1586 return test;
1587 }
1588 }
1589 return false;
1590 }
1591
1592//------------------------------------------------------------------------------
1597//------------------------------------------------------------------------------
1599 size_t complexity = 1;
1600 for (auto &b : branches) {
1601 complexity += b->get_complexity();
1602 }
1603 return complexity;
1604 }
1605
1606 public:
1607//------------------------------------------------------------------------------
1612//------------------------------------------------------------------------------
1618
1619//------------------------------------------------------------------------------
1630//------------------------------------------------------------------------------
1631 virtual void compile_preamble(std::ostringstream &stream,
1632 jit::register_map &registers,
1637 jit::preamble_map &pre_funcs,
1638 int &avail_const_mem) {
1639 if (!visited.contains(this)) {
1640 for (auto &b : branches) {
1641 b->compile_preamble(stream, registers,
1642 visited, usage,
1644 pre_funcs, avail_const_mem);
1645 }
1646
1647 visited.insert(this);
1648#ifdef SHOW_USE_COUNT
1649 usage[this] = 1;
1650 } else {
1651 ++usage[this];
1652#endif
1653 }
1654 }
1655
1656//------------------------------------------------------------------------------
1661//------------------------------------------------------------------------------
1663 return branches[index];
1664 }
1665
1666//------------------------------------------------------------------------------
1670//------------------------------------------------------------------------------
1671 virtual bool is_all_variables() const {
1672 for (auto b : branches) {
1673 const bool test = b->is_all_variables();
1674 if (!test) {
1675 return test;
1676 }
1677 }
1678 return true;
1679 }
1680
1681//------------------------------------------------------------------------------
1685//------------------------------------------------------------------------------
1686 virtual std::shared_ptr<leaf_node<T, SAFE_MATH>>
1688 return one<T, SAFE_MATH> ();
1689 }
1690 };
1691
1692//------------------------------------------------------------------------------
1696//------------------------------------------------------------------------------
1697 template<typename T>
1698 struct has_no_derivative : std::false_type {};
1699
1700//------------------------------------------------------------------------------
1710//------------------------------------------------------------------------------
1711 template<jit::float_scalar T, bool SAFE_MATH=false,
1712 class BASE_NODE=leaf_node<T, SAFE_MATH>, size_t N=1>
1713 class no_derivative : public BASE_NODE {
1714 public:
1715 template<typename S=bool>
1716 std::shared_ptr<leaf_node<T, SAFE_MATH>>
1718
1719//------------------------------------------------------------------------------
1723//------------------------------------------------------------------------------
1724 no_derivative(const std::string s)
1725 requires(std::is_base_of_v<leaf_node<T, SAFE_MATH>,
1728 leaf_node<T, SAFE_MATH> (s, 0, false) {}
1729
1730//------------------------------------------------------------------------------
1735//------------------------------------------------------------------------------
1737 const std::string s)
1738 requires(std::is_base_of_v<straight_node<T, SAFE_MATH>,
1741 straight_node<T, SAFE_MATH> (arg, s) {}
1742
1743//------------------------------------------------------------------------------
1749//------------------------------------------------------------------------------
1752 const std::string s)
1753 requires(std::is_base_of_v<branch_node<T, SAFE_MATH>,
1756 branch_node<T, SAFE_MATH> (l, r, s) {}
1757
1758//------------------------------------------------------------------------------
1765//------------------------------------------------------------------------------
1769 const std::string s)
1770 requires(std::is_base_of_v<triple_node<T, SAFE_MATH>,
1773 triple_node<T, SAFE_MATH> (l, m, r, s) {}
1774
1775//------------------------------------------------------------------------------
1780//------------------------------------------------------------------------------
1782 const std::string s)
1783 requires(std::is_base_of_v<n_branch_node<N, T, SAFE_MATH>,
1785 n_branch_node<N, T,
1786 SAFE_MATH>,
1787 N>>) :
1788 n_branch_node<N, T, SAFE_MATH> (b, s) {}
1789 };
1790
1791//******************************************************************************
1792// Variable node.
1793//******************************************************************************
1794//------------------------------------------------------------------------------
1799//------------------------------------------------------------------------------
1800 template<jit::float_scalar T, bool SAFE_MATH=false>
1801 class variable_node final : public leaf_node<T, SAFE_MATH> {
1802 private:
1804 backend::buffer<T> buffer;
1806 const std::string symbol;
1807
1808//------------------------------------------------------------------------------
1813//------------------------------------------------------------------------------
1814 static std::string to_string(variable_node<T, SAFE_MATH> *p) {
1815 return jit::format_to_string(reinterpret_cast<size_t> (p));
1816 }
1817
1818 public:
1819//------------------------------------------------------------------------------
1824//------------------------------------------------------------------------------
1825 variable_node(const size_t s,
1826 const std::string &symbol) :
1827 leaf_node<T, SAFE_MATH> (variable_node::to_string(this), 1, false),
1828 buffer(s), symbol(symbol) {}
1829
1830//------------------------------------------------------------------------------
1836//------------------------------------------------------------------------------
1837 variable_node(const size_t s, const T d,
1838 const std::string &symbol) :
1839 leaf_node<T, SAFE_MATH> (variable_node::to_string(this), 1, false),
1840 buffer(s, d), symbol(symbol) {
1841 assert(buffer.is_normal() && "NaN or Inf value.");
1842 }
1843
1844//------------------------------------------------------------------------------
1849//------------------------------------------------------------------------------
1850 variable_node(const std::vector<T> &d,
1851 const std::string &symbol) :
1852 leaf_node<T, SAFE_MATH> (variable_node::to_string(this), 1, false),
1853 buffer(d), symbol(symbol) {
1854 assert(buffer.is_normal() && "NaN or Inf value.");
1855 }
1856
1857//------------------------------------------------------------------------------
1862//------------------------------------------------------------------------------
1864 const std::string &symbol) :
1865 leaf_node<T, SAFE_MATH> (variable_node::to_string(this), 1, false),
1866 buffer(d), symbol(symbol) {
1867 assert(buffer.is_normal() && "NaN or Inf value.");
1868 }
1869
1870//------------------------------------------------------------------------------
1874//------------------------------------------------------------------------------
1876 return buffer;
1877 }
1878
1879//------------------------------------------------------------------------------
1884//------------------------------------------------------------------------------
1886 return constant<T, SAFE_MATH> (static_cast<T> (this->is_match(x)));
1887 }
1888
1889//------------------------------------------------------------------------------
1903//------------------------------------------------------------------------------
1904 virtual void compile_preamble(std::ostringstream &stream,
1905 jit::register_map &registers,
1910 jit::preamble_map &pre_funcs,
1911 int &avail_const_mem) {
1912 if (usage.find(this) == usage.end()) {
1913 usage[this] = 1;
1914#ifdef SHOW_USE_COUNT
1915 } else {
1916 ++usage[this];
1917#endif
1918 }
1919 }
1920
1921//------------------------------------------------------------------------------
1929//------------------------------------------------------------------------------
1931 compile(std::ostringstream &stream,
1932 jit::register_map &registers,
1934 const jit::register_usage &usage) {
1935 return this->shared_from_this();
1936 }
1937
1938//------------------------------------------------------------------------------
1942//------------------------------------------------------------------------------
1943 virtual void set(const T d) {
1944 buffer.set(d);
1945 }
1946
1947//------------------------------------------------------------------------------
1952//------------------------------------------------------------------------------
1953 virtual void set(const size_t index, const T d) {
1954 buffer[index] = d;
1955 }
1956
1957//------------------------------------------------------------------------------
1961//------------------------------------------------------------------------------
1962 virtual void set(const std::vector<T> &d) {
1963 buffer.set(d);
1964 }
1965
1966//------------------------------------------------------------------------------
1970//------------------------------------------------------------------------------
1971 virtual void set(const backend::buffer<T> &d) {
1972 buffer = d;
1973 }
1974
1975//------------------------------------------------------------------------------
1977//------------------------------------------------------------------------------
1978 std::string get_symbol() const {
1979 return symbol;
1980 }
1981
1982//------------------------------------------------------------------------------
1984//------------------------------------------------------------------------------
1985 virtual void to_latex() const {
1986 std::cout << get_symbol();
1987 }
1988
1989//------------------------------------------------------------------------------
1995//------------------------------------------------------------------------------
1996 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
1997 jit::register_map &registers) {
1998 if (registers.find(this) == registers.end()) {
1999 const std::string name = jit::to_string('r', this);
2000 registers[this] = name;
2001 stream << " " << name
2002 << " [label = \"" << this->get_symbol()
2003 << "\", shape = box];" << std::endl;
2004 }
2005
2006 return this->shared_from_this();
2007 }
2008
2009//------------------------------------------------------------------------------
2011//------------------------------------------------------------------------------
2012 size_t size() {
2013 return buffer.size();
2014 }
2015
2016//------------------------------------------------------------------------------
2020//------------------------------------------------------------------------------
2021 T *data() {
2022 return buffer.data();
2023 }
2024
2025//------------------------------------------------------------------------------
2029//------------------------------------------------------------------------------
2030 virtual bool is_all_variables() const {
2031 return true;
2032 }
2033
2034//------------------------------------------------------------------------------
2038//------------------------------------------------------------------------------
2039 virtual bool is_power_like() const {
2040 return true;
2041 }
2042
2043//------------------------------------------------------------------------------
2047//------------------------------------------------------------------------------
2049 return this->shared_from_this();
2050 }
2051
2052//------------------------------------------------------------------------------
2056//------------------------------------------------------------------------------
2058 return one<T, SAFE_MATH> ();
2059 }
2060
2061//------------------------------------------------------------------------------
2067//------------------------------------------------------------------------------
2068 virtual void endline(std::ostringstream &stream,
2070 const char end=';')
2071 #ifndef SHOW_USE_COUNT
2072 const
2073 #endif
2074 {
2075 stream << end << " // " << symbol
2076 #ifdef SHOW_USE_COUNT
2077 << " used " << usage.at(this)
2078 #endif
2079 << std::endl;
2080 }
2081 };
2082
2083//------------------------------------------------------------------------------
2091//------------------------------------------------------------------------------
2092 template<jit::float_scalar T, bool SAFE_MATH=false>
2094 const std::string &symbol) {
2095 return std::make_shared<variable_node<T, SAFE_MATH>> (s, symbol);
2096 }
2097
2098//------------------------------------------------------------------------------
2107//------------------------------------------------------------------------------
2108 template<jit::float_scalar T, bool SAFE_MATH=false>
2109 shared_leaf<T, SAFE_MATH> variable(const size_t s, const T d,
2110 const std::string &symbol) {
2111 return std::make_shared<variable_node<T, SAFE_MATH>> (s, d, symbol);
2112 }
2113
2114//------------------------------------------------------------------------------
2122//------------------------------------------------------------------------------
2123 template<jit::float_scalar T, bool SAFE_MATH=false>
2124 shared_leaf<T, SAFE_MATH> variable(const std::vector<T> &d,
2125 const std::string &symbol) {
2126 return std::make_shared<variable_node<T, SAFE_MATH>> (d, symbol);
2127 }
2128
2129//------------------------------------------------------------------------------
2137//------------------------------------------------------------------------------
2138 template<jit::float_scalar T, bool SAFE_MATH=false>
2140 const std::string &symbol) {
2141 return std::make_shared<variable_node<T, SAFE_MATH>> (d, symbol);
2142 }
2143
2145 template<jit::float_scalar T, bool SAFE_MATH=false>
2146 using shared_variable = std::shared_ptr<variable_node<T, SAFE_MATH>>;
2148 template<jit::float_scalar T, bool SAFE_MATH=false>
2149 using input_nodes = std::vector<shared_variable<T, SAFE_MATH>>;
2151 template<jit::float_scalar T, bool SAFE_MATH=false>
2152 using map_nodes = std::vector<std::pair<shared_leaf<T, SAFE_MATH>,
2155 template<jit::float_scalar T, bool SAFE_MATH=false>
2156 using copy_nodes = std::vector<std::pair<shared_variable<T, SAFE_MATH>,
2158
2159//------------------------------------------------------------------------------
2167//------------------------------------------------------------------------------
2168 template<jit::float_scalar T, bool SAFE_MATH=false>
2170 return std::dynamic_pointer_cast<variable_node<T, SAFE_MATH>> (x);
2171 }
2172
2173//******************************************************************************
2174// Pseudo variable node.
2175//******************************************************************************
2176//------------------------------------------------------------------------------
2185//------------------------------------------------------------------------------
2186 template<jit::float_scalar T, bool SAFE_MATH=false>
2187 class pseudo_variable_node final : public straight_node<T, SAFE_MATH> {
2188 private:
2189//------------------------------------------------------------------------------
2194//------------------------------------------------------------------------------
2195 static std::string to_string(leaf_node<T, SAFE_MATH> *p) {
2196 return jit::format_to_string(reinterpret_cast<size_t> (p));
2197 }
2198
2199 public:
2200//------------------------------------------------------------------------------
2204//------------------------------------------------------------------------------
2207
2208//------------------------------------------------------------------------------
2213//------------------------------------------------------------------------------
2215 return constant<T, SAFE_MATH> (static_cast<T> (this->is_match(x)));
2216 }
2217
2218//------------------------------------------------------------------------------
2220//------------------------------------------------------------------------------
2221 virtual void to_latex() const {
2222 std::cout << "\\left(";
2223 this->arg->to_latex();
2224 std::cout << "\\right)";
2225 }
2226
2227//------------------------------------------------------------------------------
2231//------------------------------------------------------------------------------
2232 virtual bool is_all_variables() const {
2233 return true;
2234 }
2235
2236//------------------------------------------------------------------------------
2240//------------------------------------------------------------------------------
2241 virtual bool is_power_like() const {
2242 return true;
2243 }
2244
2245//------------------------------------------------------------------------------
2249//------------------------------------------------------------------------------
2251 return this->arg->get_power_base();
2252 }
2253
2254//------------------------------------------------------------------------------
2258//------------------------------------------------------------------------------
2260 return this->arg->get_power_exponent();
2261 }
2262
2263//------------------------------------------------------------------------------
2267//------------------------------------------------------------------------------
2268 virtual bool has_pseudo() const {
2269 return true;
2270 }
2271
2272//------------------------------------------------------------------------------
2276//------------------------------------------------------------------------------
2278 return this->arg;
2279 }
2280
2281//------------------------------------------------------------------------------
2287//------------------------------------------------------------------------------
2288 virtual shared_leaf<T, SAFE_MATH> to_vizgraph(std::stringstream &stream,
2289 jit::register_map &registers) {
2290 if (registers.find(this) == registers.end()) {
2291 const std::string name = jit::to_string('r', this);
2292 registers[this] = name;
2293 stream << " " << name
2294 << " [label = \"pseudo_variable\", shape = oval, style = filled, fillcolor = blue, fontcolor = white];" << std::endl;
2295
2296 auto a = this->arg->to_vizgraph(stream, registers);
2297 stream << " " << name << " -- " << registers[a.get()] << ";" << std::endl;
2298 }
2299
2300 return this->shared_from_this();
2301 }
2302 };
2303
2304//------------------------------------------------------------------------------
2312//------------------------------------------------------------------------------
2313 template<jit::float_scalar T, bool SAFE_MATH=false>
2315 return std::make_shared<pseudo_variable_node<T, SAFE_MATH>> (x);
2316 }
2317
2319 template<jit::float_scalar T, bool SAFE_MATH=false>
2320 using shared_pseudo_variable = std::shared_ptr<pseudo_variable_node<T, SAFE_MATH>>;
2321
2322//------------------------------------------------------------------------------
2330//------------------------------------------------------------------------------
2331 template<jit::float_scalar T, bool SAFE_MATH=false>
2333 return std::dynamic_pointer_cast<pseudo_variable_node<T, SAFE_MATH>> (x);
2334 }
2335}
2336
2337#endif /* node_h */
Class signature to implement compute backends.
Class representing a generic buffer.
Definition backend.hpp:29
bool is_normal() const
Check for normal values.
Definition backend.hpp:267
bool has_zero() const
Is any element zero.
Definition backend.hpp:141
void set(const T d)
Assign a constant value.
Definition backend.hpp:92
Class representing a branch node.
Definition node.hpp:1337
virtual bool is_all_variables() const
Test if node acts like a variable.
Definition node.hpp:1438
branch_node(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r, const std::string s, const size_t count, const bool pseudo)
Assigns the left and right branches.
Definition node.hpp:1369
shared_leaf< T, SAFE_MATH > get_left() const
Get the left branch.
Definition node.hpp:1420
shared_leaf< T, SAFE_MATH > get_right() const
Get the right branch.
Definition node.hpp:1429
virtual std::shared_ptr< leaf_node< T, SAFE_MATH > > get_power_exponent() const
Get the exponent of a power.
Definition node.hpp:1449
virtual void compile_preamble(std::ostringstream &stream, jit::register_map &registers, jit::visiter_map &visited, jit::register_usage &usage, jit::texture1d_list &textures1d, jit::texture2d_list &textures2d, jit::preamble_map &pre_funcs, int &avail_const_mem)
Compile preamble.
Definition node.hpp:1389
branch_node(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r, const std::string s)
Assigns the left and right branches.
Definition node.hpp:1353
shared_leaf< T, SAFE_MATH > right
Right branch of the tree.
Definition node.hpp:1342
shared_leaf< T, SAFE_MATH > left
Left branch of the tree.
Definition node.hpp:1340
Class representing data that cannot change.
Definition node.hpp:903
virtual shared_leaf< T, SAFE_MATH > get_power_exponent() const
Get the exponent of a power.
Definition node.hpp:1096
virtual void to_latex() const
Convert the node to latex.
Definition node.hpp:1031
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition node.hpp:961
virtual shared_leaf< T, SAFE_MATH > get_power_base()
Get the base of a power.
Definition node.hpp:1087
bool is(const T d)
Check if the constant is value.
Definition node.hpp:1015
virtual backend::buffer< T > evaluate()
Evaluate method.
Definition node.hpp:937
virtual bool is_match(shared_leaf< T, SAFE_MATH > x)
Query if the nodes match.
Definition node.hpp:999
constant_node(const backend::buffer< T > &d)
Construct a constant node from a vector.
Definition node.hpp:924
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition node.hpp:1042
virtual shared_leaf< T, SAFE_MATH > df(shared_leaf< T, SAFE_MATH > x)
Transform node to derivative.
Definition node.hpp:947
virtual bool is_constant() const
Test if node is a constant.
Definition node.hpp:1060
virtual bool has_constant_zero() const
Test the constant node has a zero.
Definition node.hpp:1069
bool is_integer()
Check if the value is an integer.
Definition node.hpp:1022
virtual bool is_power_like() const
Test if the node acts like a power of variable.
Definition node.hpp:1078
Index node.
Definition node.hpp:744
virtual void to_latex() const
Convert the node to latex.
Definition node.hpp:814
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition node.hpp:825
virtual shared_leaf< T, SAFE_MATH > get_power_exponent() const
Get the exponent of a power.
Definition node.hpp:842
index_node()
Construct a constant node from a vector.
Definition node.hpp:759
virtual std::shared_ptr< leaf_node< T, SAFE_MATH > > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition node.hpp:791
virtual backend::buffer< T > evaluate()
Evaluate method.
Definition node.hpp:767
virtual shared_leaf< T, SAFE_MATH > df(shared_leaf< T, SAFE_MATH > x)
Transform node to derivative.
Definition node.hpp:777
Class representing a node leaf.
Definition node.hpp:371
virtual ~leaf_node()
Destructor.
Definition node.hpp:399
virtual void compile_preamble(std::ostringstream &stream, jit::register_map &registers, jit::visiter_map &visited, jit::register_usage &usage, jit::texture1d_list &textures1d, jit::texture2d_list &textures2d, jit::preamble_map &pre_funcs, int &avail_const_mem)
Compile preamble.
Definition node.hpp:445
virtual void set(const std::vector< T > &d)
Set the value of variable data.
Definition node.hpp:518
virtual bool is_power_like() const
Test if the node acts like a power of variable.
Definition node.hpp:585
virtual bool is_match(std::shared_ptr< leaf_node< T, SAFE_MATH > > x)
Query if the nodes match.
Definition node.hpp:483
virtual std::shared_ptr< leaf_node< T, SAFE_MATH > > get_power_exponent() const =0
Get the exponent of a power.
virtual std::shared_ptr< leaf_node< T, SAFE_MATH > > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)=0
Compile the node.
T base
Type def to retrieve the backend type.
Definition node.hpp:686
virtual void to_latex() const
Convert the node to latex.
Definition node.hpp:530
const bool contains_pseudo
Node contains pseudo variables.
Definition node.hpp:380
virtual std::shared_ptr< leaf_node< T, SAFE_MATH > > remove_pseudo()
Remove pseudo variable nodes.
Definition node.hpp:642
virtual void set(const backend::buffer< T > &d)
Set the value of variable data.
Definition node.hpp:525
static thread_local caches_t caches
A per thread instance of the cache structure.
Definition node.hpp:683
virtual bool is_all_variables() const
Test if all the sub-nodes terminate in variables.
Definition node.hpp:574
virtual void endline(std::ostringstream &stream, const jit::register_usage &usage, const char end=';') const
End a line in the kernel source.
Definition node.hpp:653
virtual bool is_constant() const
Test if node is a constant.
Definition node.hpp:547
virtual void set(const size_t index, const T d)
Set the value of variable data.
Definition node.hpp:510
virtual std::shared_ptr< leaf_node< T, SAFE_MATH > > to_vizgraph(std::stringstream &stream, jit::register_map &registers)=0
Convert the node to vizgraph.
virtual std::shared_ptr< leaf_node< T, SAFE_MATH > > get_power_base()
Get the base of a power.
Definition node.hpp:596
virtual std::shared_ptr< leaf_node< T, SAFE_MATH > > reduce()
Reduction method.
Definition node.hpp:415
leaf_node(const std::string s, const size_t count, const bool pseudo)
Construct a basic node.
Definition node.hpp:390
virtual bool has_constant_zero() const
Test the constant node has a zero.
Definition node.hpp:556
virtual std::shared_ptr< leaf_node< T, SAFE_MATH > > df(std::shared_ptr< leaf_node< T, SAFE_MATH > > x)
Transform node to derivative.
Definition node.hpp:426
virtual void set(const T d)
Set the value of variable data.
Definition node.hpp:502
const size_t complexity
Graph complexity.
Definition node.hpp:376
virtual backend::buffer< T > evaluate()=0
Evaluate method.
bool is_power_base_match(std::shared_ptr< leaf_node< T, SAFE_MATH > > x)
Check if the base of the powers match.
Definition node.hpp:493
size_t get_complexity() const
Get the number of nodes in the subgraph.
Definition node.hpp:624
virtual bool has_pseudo() const
Query if the node contains pseudo variables.
Definition node.hpp:633
const size_t hash
Hash for node.
Definition node.hpp:374
std::unordered_map< size_t, std::shared_ptr< leaf_node< T, SAFE_MATH > > > df_cache
Cache derivative terms.
Definition node.hpp:378
bool is_normal()
Test if the result is normal.
Definition node.hpp:565
size_t get_hash() const
Get the hash for the node.
Definition node.hpp:615
Class representing a N branch node.
Definition node.hpp:1571
size_t total_complexity(std::array< shared_leaf< T, SAFE_MATH >, N > &branches)
Check if any sub-node has a pseudo variable.
Definition node.hpp:1598
virtual std::shared_ptr< leaf_node< T, SAFE_MATH > > get_power_exponent() const
Get the exponent of a power.
Definition node.hpp:1687
virtual bool is_all_variables() const
Test if node acts like a variable.
Definition node.hpp:1671
bool any_has_pseudo(std::array< shared_leaf< T, SAFE_MATH >, N > &branches)
Check if any sub-node has a pseudo variable.
Definition node.hpp:1582
n_branch_node(std::array< shared_leaf< T, SAFE_MATH >, N > branches, const std::string s)
Reduces and assigns the branches.
Definition node.hpp:1613
std::array< shared_leaf< T, SAFE_MATH >, N > branches
Branches of the tree.
Definition node.hpp:1574
virtual void compile_preamble(std::ostringstream &stream, jit::register_map &registers, jit::visiter_map &visited, jit::register_usage &usage, jit::texture1d_list &textures1d, jit::texture2d_list &textures2d, jit::preamble_map &pre_funcs, int &avail_const_mem)
Compile preamble.
Definition node.hpp:1631
shared_leaf< T, SAFE_MATH > get_arg(const size_t index) const
Get the Nth arg.
Definition node.hpp:1662
Nodes without derivatives.
Definition node.hpp:1713
std::shared_ptr< leaf_node< T, SAFE_MATH > > df(std::shared_ptr< leaf_node< T, SAFE_MATH > > x)
Transform node to derivative.
no_derivative(std::array< shared_leaf< T, SAFE_MATH >, N > b, const std::string s)
Constructor for base n branch nodes base classes.
Definition node.hpp:1781
no_derivative(const std::string s)
Constructor for base leaf nodes base classes.
Definition node.hpp:1724
no_derivative(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > m, shared_leaf< T, SAFE_MATH > r, const std::string s)
Constructor for base triple nodes base classes.
Definition node.hpp:1766
no_derivative(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > r, const std::string s)
Constructor for base branch nodes base classes.
Definition node.hpp:1750
no_derivative(shared_leaf< T, SAFE_MATH > arg, const std::string s)
Constructor for straight node base classes.
Definition node.hpp:1736
Class representing a subexpression that acts like a variable.
Definition node.hpp:2187
virtual void to_latex() const
Convert the node to latex.
Definition node.hpp:2221
virtual shared_leaf< T, SAFE_MATH > df(shared_leaf< T, SAFE_MATH > x)
Transform node to derivative.
Definition node.hpp:2214
virtual bool is_power_like() const
Test if the node acts like a power of variable.
Definition node.hpp:2241
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition node.hpp:2288
virtual shared_leaf< T, SAFE_MATH > get_power_exponent() const
Get the exponent of a power.
Definition node.hpp:2259
virtual bool is_all_variables() const
Test if node acts like a variable.
Definition node.hpp:2232
virtual shared_leaf< T, SAFE_MATH > remove_pseudo()
Remove pseudo variable nodes.
Definition node.hpp:2277
virtual shared_leaf< T, SAFE_MATH > get_power_base()
Get the base of a power.
Definition node.hpp:2250
virtual bool has_pseudo() const
Query if the node contains pseudo variables.
Definition node.hpp:2268
pseudo_variable_node(shared_leaf< T, SAFE_MATH > a)
Construct a pseudo variable node.
Definition node.hpp:2205
Class representing a straight node.
Definition node.hpp:1219
virtual shared_leaf< T, SAFE_MATH > get_power_exponent() const
Get the exponent of a power.
Definition node.hpp:1319
shared_leaf< T, SAFE_MATH > arg
Argument.
Definition node.hpp:1222
virtual backend::buffer< T > evaluate()
Evaluate method.
Definition node.hpp:1241
shared_leaf< T, SAFE_MATH > get_arg() const
Get the argument.
Definition node.hpp:1301
virtual void compile_preamble(std::ostringstream &stream, jit::register_map &registers, jit::visiter_map &visited, jit::register_usage &usage, jit::texture1d_list &textures1d, jit::texture2d_list &textures2d, jit::preamble_map &pre_funcs, int &avail_const_mem)
Compile preamble.
Definition node.hpp:1257
straight_node(shared_leaf< T, SAFE_MATH > a, const std::string s)
Construct a straight node.
Definition node.hpp:1231
virtual bool is_all_variables() const
Test if node acts like a variable.
Definition node.hpp:1310
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition node.hpp:1289
Class representing a triple branch node.
Definition node.hpp:1467
shared_leaf< T, SAFE_MATH > get_middle() const
Get the middle branch.
Definition node.hpp:1541
virtual bool is_all_variables() const
Test if node acts like a variable.
Definition node.hpp:1550
virtual void compile_preamble(std::ostringstream &stream, jit::register_map &registers, jit::visiter_map &visited, jit::register_usage &usage, jit::texture1d_list &textures1d, jit::texture2d_list &textures2d, jit::preamble_map &pre_funcs, int &avail_const_mem)
Compile preamble.
Definition node.hpp:1506
triple_node(shared_leaf< T, SAFE_MATH > l, shared_leaf< T, SAFE_MATH > m, shared_leaf< T, SAFE_MATH > r, const std::string s)
Reduces and assigns the left and right branches.
Definition node.hpp:1481
shared_leaf< T, SAFE_MATH > middle
Middle branch of the tree.
Definition node.hpp:1470
Class representing data that can change.
Definition node.hpp:1801
virtual shared_leaf< T, SAFE_MATH > get_power_base()
Get the base of a power.
Definition node.hpp:2048
variable_node(const backend::buffer< T > &d, const std::string &symbol)
Construct a variable node from backend buffer.
Definition node.hpp:1863
virtual void endline(std::ostringstream &stream, const jit::register_usage &usage, const char end=';') const
End a line in the kernel source.
Definition node.hpp:2068
virtual void compile_preamble(std::ostringstream &stream, jit::register_map &registers, jit::visiter_map &visited, jit::register_usage &usage, jit::texture1d_list &textures1d, jit::texture2d_list &textures2d, jit::preamble_map &pre_funcs, int &avail_const_mem)
Compile preamble.
Definition node.hpp:1904
virtual bool is_all_variables() const
Test if node acts like a variable.
Definition node.hpp:2030
virtual shared_leaf< T, SAFE_MATH > df(shared_leaf< T, SAFE_MATH > x)
Transform node to derivative.
Definition node.hpp:1885
variable_node(const size_t s, const T d, const std::string &symbol)
Construct a variable node from a scalar.
Definition node.hpp:1837
virtual void to_latex() const
Convert the node to latex.
Definition node.hpp:1985
size_t size()
Get the size of the variable buffer.
Definition node.hpp:2012
virtual shared_leaf< T, SAFE_MATH > to_vizgraph(std::stringstream &stream, jit::register_map &registers)
Convert the node to vizgraph.
Definition node.hpp:1996
virtual backend::buffer< T > evaluate()
Evaluate method.
Definition node.hpp:1875
virtual shared_leaf< T, SAFE_MATH > compile(std::ostringstream &stream, jit::register_map &registers, const jit::register_map &thread_mem, const jit::register_usage &usage)
Compile the node.
Definition node.hpp:1931
T * data()
Get a pointer to raw buffer.
Definition node.hpp:2021
virtual void set(const T d)
Set the value of variable data.
Definition node.hpp:1943
virtual bool is_power_like() const
Test if the node acts like a power of variable.
Definition node.hpp:2039
virtual void set(const backend::buffer< T > &d)
Set the value of variable data.
Definition node.hpp:1971
virtual void set(const size_t index, const T d)
Set the value of variable data.
Definition node.hpp:1953
variable_node(const size_t s, const std::string &symbol)
Construct a variable node with a size.
Definition node.hpp:1825
virtual void set(const std::vector< T > &d)
Set the value of variable data.
Definition node.hpp:1962
variable_node(const std::vector< T > &d, const std::string &symbol)
Construct a variable node from a vector.
Definition node.hpp:1850
std::string get_symbol() const
Get Symbol.
Definition node.hpp:1978
virtual shared_leaf< T, SAFE_MATH > get_power_exponent() const
Get the exponent of a power.
Definition node.hpp:2057
Complex scalar concept.
Definition register.hpp:25
Float scalar concept.
Definition register.hpp:30
subroutine assert(test, message)
Assert check.
Definition f_binding_test.f90:38
Name space for graph nodes.
Definition arithmetic.hpp:13
constexpr shared_leaf< T, SAFE_MATH > zero()
Forward declare for zero.
Definition node.hpp:1154
std::shared_ptr< variable_node< T, SAFE_MATH > > shared_variable
Convenience type alias for shared variable nodes.
Definition node.hpp:2146
shared_leaf< T, SAFE_MATH > index()
Construct an index.
Definition node.hpp:856
constexpr shared_leaf< T, SAFE_MATH > none()
Create a one constant.
Definition node.hpp:1180
void make_vizgraph(shared_leaf< T, SAFE_MATH > node)
Build the vizgraph input.
Definition node.hpp:721
constexpr shared_leaf< T, SAFE_MATH > one()
Forward declare for one.
Definition node.hpp:1167
std::vector< shared_variable< T, SAFE_MATH > > input_nodes
Convenience type alias for a vector of inputs.
Definition node.hpp:2149
shared_constant< T, SAFE_MATH > constant_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a constant node.
Definition node.hpp:1202
shared_variable< T, SAFE_MATH > variable_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a variable node.
Definition node.hpp:2169
shared_index< T, SAFE_MATH > index_cast(shared_leaf< T, SAFE_MATH > x)
Cast to a index node.
Definition node.hpp:889
constexpr T i
Convenience type for imaginary constant.
Definition node.hpp:1186
shared_leaf< T, SAFE_MATH > constant(const backend::buffer< T > &d)
Construct a constant.
Definition node.hpp:1111
std::vector< std::pair< shared_variable< T, SAFE_MATH >, shared_variable< T, SAFE_MATH > > > copy_nodes
Convenience type alias for copying buffers.
Definition node.hpp:2157
shared_leaf< T, SAFE_MATH > variable(const size_t s, const std::string &symbol)
Construct a variable.
Definition node.hpp:2093
std::shared_ptr< pseudo_variable_node< T, SAFE_MATH > > shared_pseudo_variable
Convenience type alias for shared pseudo variable nodes.
Definition node.hpp:2320
std::shared_ptr< leaf_node< T, SAFE_MATH > > shared_leaf
Convenience type alias for shared leaf nodes.
Definition node.hpp:691
std::shared_ptr< index_node< T, SAFE_MATH > > shared_index
Convenience type alias for shared index nodes.
Definition node.hpp:877
std::vector< std::pair< shared_leaf< T, SAFE_MATH >, shared_variable< T, SAFE_MATH > > > map_nodes
Convenience type alias for mapping end codes back to inputs.
Definition node.hpp:2153
constexpr shared_leaf< T, SAFE_MATH > null_leaf()
Create a null leaf.
Definition node.hpp:701
std::shared_ptr< constant_node< T, SAFE_MATH > > shared_constant
Convenience type alias for shared constant nodes.
Definition node.hpp:1190
std::vector< shared_leaf< T, SAFE_MATH > > output_nodes
Convenience type alias for a vector of output nodes.
Definition node.hpp:706
shared_leaf< T, SAFE_MATH > pseudo_variable(shared_leaf< T, SAFE_MATH > x)
Define pseudo variable convenience function.
Definition node.hpp:2314
shared_pseudo_variable< T, SAFE_MATH > pseudo_variable_cast(shared_leaf< T, SAFE_MATH > &x)
Cast to a pseudo variable node.
Definition node.hpp:2332
std::unordered_set< void * > visiter_map
Type alias for listing visited nodes.
Definition register.hpp:263
std::string format_to_string(const T value)
Convert a value to a string while avoiding locale.
Definition register.hpp:213
std::unordered_map< void *, size_t > register_usage
Type alias for counting register usage.
Definition register.hpp:261
std::unordered_set< std::string > preamble_map
Type alias for preamble defined functions.
Definition register.hpp:269
std::unordered_map< void *, std::string > register_map
Type alias for mapping node pointers to register names.
Definition register.hpp:259
constexpr bool use_cuda()
Test to use Cuda.
Definition register.hpp:68
std::unordered_map< void *, std::array< size_t, 2 > > texture2d_list
Type alias for indexing 2D textures.
Definition register.hpp:267
std::unordered_map< void *, size_t > texture1d_list
Type alias for indexing 1D textures.
Definition register.hpp:265
std::string to_string(const char prefix, const NODE *pointer)
Convert a graph::leaf_node pointer to a string.
Definition register.hpp:247
void test()
Test function.
Definition no_derivative_test.cpp:67
Type trait for not having a valid derivative.
Definition node.hpp:1698
Data structure to contain the two caches.
Definition node.hpp:675
std::unordered_map< size_t, std::shared_ptr< leaf_node< T, SAFE_MATH > > > nodes
Cache of node.
Definition node.hpp:677
std::unordered_map< size_t, backend::buffer< T > > backends
Cache of backend buffers.
Definition node.hpp:679