Giter VIP home page Giter VIP logo

crave's People

Contributors

finnhaedicke avatar grossed avatar nbruns1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

crave's Issues

Vector randomization & constraints don't work correctly.

I'm trying out the latest code in the development branch, using boost 1.57.0 on linux (Gentoo). When I run ex5_vec_constr, the produced output is (only the first 3 iterations are shown):

src_addr_vec = 28 8 12 4 0
dest_addr_vec = 8 16 24 32 40
data_vec = 4294901760 0 10 100 10 100 10 100 10 100

src_addr_vec = 212 252 240 244 248 220 232 236 228 224
dest_addr_vec = 7 15 23 31 39 47 55 63 71 79
data_vec = 4294901760 0 10 100 10 100 10 100 10 100 10 100 10 100 10 100 10 100 10 100

src_addr_vec = 20 24 28 8 12 4 0
dest_addr_vec = 12 20 28 36 44 52 60
data_vec = 4294901760 0 10 100 10 100 10 100 10 100 10 100 10 100

The printed elements have the following types:

crave::rand_vec<unsigned> src_addr_vec;
crave::rand_vec<unsigned> dest_addr_vec;
crave::rand_vec<unsigned> data_vec;

There seem to be a couple of issues with the generated values:

  • Values in src_addr_vec often repeat across consecutive randomizations. The constraints on src_addr_vec's values don't enforce this repetition. On the other hand, the generated values do seem to conform to the constraints, they're just not uniformly randomly distributed. Here's the constraints:
constraint(foreach (src_addr_vec(), src_addr_vec()[_i] < 0xFF));
constraint(foreach (src_addr_vec(), src_addr_vec()[_i] % 4 == 0));
constraint(unique(src_addr_vec()));
  • The constraints on dest_addr_vec require its first element to be >= 0 and < 15. All other elements depend on this:
constraint(foreach (dest_addr_vec(), if_then(_i == 0, dest_addr_vec()[_i] < 0xF)));
constraint(foreach (dest_addr_vec(), dest_addr_vec()[_i] == dest_addr_vec()[_i - 1] + 8));
constraint(unique(dest_addr_vec()));

However, after randomizing the vector 100 times and inspecting the 1st element (index 0), it's clear that it's not uniformly randomly distributed between 0 & 14 at all. The only values assigned to it are 7, 8 and 11.

  • The constraint on data_vec's values don't seem to be upheld. Here's the constraint:
constraint(foreach (data_vec(), if_then_else(_i % 2 == 0, data_vec()[_i] <= 10,
  data_vec()[_i] == data_vec()[_i - 1] * data_vec()[_i - 1])));

The 1st element (index 0) should be <= 10, which clearly isn't the case. For the 2nd element, the constraint matches, because static_cast(4294901760 โ‹… 4294901760) == 0. Then for all the next elements, there's no randomness at all anymore.

I haven't been able to figure out from the code why this is happening, but I haven't had much time to look into it.

Constraint specified using multiplication operator gives wrong values

I have defined a constraint as shown below

Constraint: CHECK( crave::solve(x() >= 0, y() >= 0, x() * y() == 4 ));
The expected answer is x=2, y=2. But I am seeing values that are very different

Run1:
x y
1158303798 701293606

Run2:
x y
733933413 108964276

Please look into this issue. Any help regarding this will be really useful.

Randomization of SystemC types > 64 bit not supported

Creating an e.g. crave::randv<sc_dt::sc_bv<128>> object works fine. However, when next() is called on this object, only bits 0-63 will be set, the remaining ones will all be zero. This is hardcoded in SystemC.hpp's next function, where an std::int64 generator is used.

I'm not sure how difficult it would be to fix this. Extending the random number generation to generate enough random bits seems doable. Modifying generated constraints to be correct seems like a more difficult task.

Alternatively, construction of such objects could be prevented with some SFINAE, e.g.:

/* Boost is preferred/required over C++14 for compatibility with e.g. QuestaSim. */
template <int N, std::enable_if_t<N <= 64, int> = 0>
struct randv<sc_dt::sc_bv<N>> : public randv_base<sc_dt::sc_bv<N>> { /* etc */ };

Vector Constraint with if_then_else not working when if statement is about a separate random variable

Hi,

I am trying to randomize the elements of a crv_vector depending on the value of a separate crv_variable. When trying to use a different crv_variable in the if-statement of the if-then-else construct, I am getting a segmentation fault. Using GDB, this fault is occurring at Line 48 of VectorGenerator.cpp (Line 48 if the accellera-contribution branch) and it seems like it is trying to dereference a NULL pointer.

How can I use a CRAVE variable ( crv_variable <enum_data_type> size ) in an if-then-else for a vector constraint for randomizing each vector element? See "c_len_vec" constraint below, specifically the last foreach loop.

c_num_mcs = {
num_mcs() >= 1,
if_then_else(
size() == TYPE_SIZE_LONG, //This works, and so we assumed that this would work for a vector (see below)
num_mcs() <= this->max_mcs_long,
num_mcs() <= this->max_mcs_short
)
};

    c_len_vec = {
        len_vec().size() == num_mcs(),
        foreach(len_vec(), len_vec()[_i] >= 1),

    //This foreach loop results in a segmentation fault.
        foreach(len_vec(),
            if_then_else(
                size() == TYPE_SIZE_LONG,                        // This line results in a Segmentation Fault.
                len_vec()[_i] <= this->max_mcs_len_long,
                len_vec()[_i] <= this->max_mcs_len_short
            )
        )
    };

interclass constraints not working

I have two classes with simple public members, when I provide constraints which define dependency between classes, I dont see any randomization
e.g.

#include <crave/ConstrainedRandom.hpp>
#include <crave/experimental/Experimental.hpp>
#include <boost/format.hpp>
#include <iostream>

using namespace crave;
class class_a : public crv_sequence_item {
 public:
 crv_variable<unsigned int> num;
 
  crv_constraint legal_num_class_C{ num() < 10 };

 class_a(crave::crv_object_name name = "class_a") {
    
 }
 void print(){
   std::cout<<" CLASS A num "<<num<<"\n";

 }
};

class class_b : public crv_sequence_item {
 public:
 crv_variable<unsigned int> powr;

 class_b(crave::crv_object_name name = "class_b") {
   
 }
 void print(){
   std::cout<<" CLASS B POW "<<powr<<"\n";

 }
};


int main(int argc, char* argv[]) {
  crave::init("crave.cfg");
  crave::set_global_seed(123456789);

  class_a a("a");
  class_b b("b");

  crv_constraint legal_pow_class_{ b.powr() == (1<<a.num()) };

  CHECK(a.randomize());
  CHECK(b.randomize());
  a.print();
  b.print();
}

I get values of num and powr as zero when printed
CLASS A num 0
CLASS B POW 0

(In)equality operators don't always behave symmetrical

The (in)equality operators defined for crave::randv<sc_dt::sc_bv<W>> behave asymmetrical once W > 64. Try for example the following code:

#include <crave/ConstrainedRandom.hpp>
#include <crave/SystemC.hpp>

#include <systemc>

#include <iomanip>
#include <iostream>

int sc_main (int argc, char ** argv) {
  std::uint64_t const c_IntOnes = ~(0ull);
  sc_dt::sc_bv<128> const c_BvOnes = ~sc_dt::sc_bv<128>(0);

  auto largeBv = crave::randv<sc_dt::sc_bv<128>>(nullptr);
  largeBv = c_BvOnes;

  std::cout << "c_IntOnes = 0x" << std::hex << c_IntOnes << std::dec << "\n";
  std::cout << "largeBv   = 0b" << largeBv << "\n";
  std::cout << "\n";

  std::cout << std::boolalpha;
  std::cout << "(largeBv   == c_IntOnes) = " << static_cast<bool>(largeBv == c_IntOnes) << "\n";
  std::cout << "(c_IntOnes == largeBv)   = " << static_cast<bool>(c_IntOnes == largeBv) << "\n";
  std::cout << "\n";

  return 0;
}

The cause seems to be the promotion of c_IntOnes to sc_dt::int64 when calling operator== (sc_dt::int64 const, randv<Typename<N>> const &). I tried my hand at fixing the RANDV_SCDT_BINARY_OPERATOR macro, but so far haven't been able to come up with the proper SFINAE to make it work/compile in all cases.

Also note that these (in)equality operators all return sc_dt::int64 instead of bool.

Sudoku Examples Stalling?

I have successfully built CRAVE using the default build with the Boolector and CUDD solvers. I can build and run most of the examples except either of the sudoku ones. Is the selection of Boolector and CUDD solvers capable of solving the constraints for these sudoku examples? The examples will start simulating, but then go on for hours without finishing.

Thanks,
Peter

randv (and related classes) don't use RAII

When a crave::randv object is constructed with a non-nullptr value for the parent pointer, it registers itself with said parent (through randv_base::add_base_child). However, upon destruction it doesn't deregister itself from the parent. This causes dangling pointers and the undefined behavior that comes with it when rand_base::next() is called on the parent (so far I've seen SIGSERV and "abstract virtual called").

Furthermore, since there's copy constructors defined for the randv_base and randv types, move construction and assignment are both implicitly disabled. Just "thinking out loud", it seems to me that when a parent class is moved, it should be able to call some sort of "move_parent()" on the randv child objects. Such move_parent functionality would be the equivalent of remove_base_child (which currently doesn't exist) followed by add_base_child. This move_parent could then also be called by a user's custom objects where appropriate.

Similar things can most likely be said about rand_obj and its add_obj_child function (although I didn't check this thoroughly yet).

Below is a minimalistic example that triggers UB through derefencing pointers to destructed objects. I know crave::rand_vec exists, but I don't see why this example using std::vector shouldn't be able to work if the above issues are solved.

#include <crave/ConstrainedRandom.hpp>

#include <cstdint>
#include <iostream>
#include <vector>

struct custom_item : public crave::rand_obj {
  using base_type = crave::rand_obj;

  custom_item (crave::rand_obj * parent = nullptr)
    : base_type(parent), vectorSize_(this)
  {
    constraint(0 < vectorSize_() && vectorSize_() <= 10);
  }

  virtual bool next () override {
    bool const result = base_type::next();
    post_randomize();
    return result;
  }

  virtual void post_randomize () {
    items_.clear();
    items_.reserve(vectorSize_);
    for (std::size_t count = 0; count < vectorSize_; ++count) {
      items_.emplace_back(this);
      items_.back().next();
    }
  }

  crave::randv<std::size_t> vectorSize_;
  std::vector<crave::randv<int>> items_ = {};
};

std::ostream & operator<< (std::ostream & os, custom_item const & obj) {
  os << "elements [" << obj.vectorSize_ << "]: ";
  for (auto const & entry : obj.items_) { os << entry << ' '; }
  return os;
}

int main () {
  crave::init("crave.cfg");
  crave::set_global_seed(1234567890); // Raises SIGSERV.
  //crave::set_global_seed(2234567890); // Raises abstract virtual called.

  custom_item anItem;

  for (int i = 0; i < 5; i++) {
    CHECK(anItem.next());
    std::cout << anItem << '\n';
  }
}

Thread safety

Just a question: am i correct in assuming that crave is not thread safe, i.e. it's not possible to create random stimuli from multiple linux thread contexts in parallel even if those threads have their own private rand_obj's to manage?

Thanks!

How to know what seed was used?

I set_global_seed to 0 and run multiple times, and eventually hit a failure in my test. How can I know what seed was used for that test?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.