options join(options const & opts1, options const & opts2) { sexpr r = opts2.m_value; for_each(opts1.m_value, [&](sexpr const & p) { if (!opts2.contains(to_name(car(p)))) r = cons(p, r); }); return options(r); }
inline edges::edges( nodes * in, nodes * out, options const & opts, vec3i const & stride, vec3i const & in_size, task_manager & tm, filter_tag ) : options_(opts) , size_(in_size) , tm_(tm) { size_t n = in->num_out_nodes(); size_t m = out->num_in_nodes(); ZI_ASSERT((n>0)&&m>0); edges_.resize(n*m); filters_.resize(n*m); waiter_.set(n*m); real eta = opts.optional_as<real>("eta", 0.1); real mom = opts.optional_as<real>("momentum", 0.0); real wd = opts.optional_as<real>("weight_decay", 0.0); auto sz = opts.require_as<ovec3i>("size"); size_ = sz; for ( size_t k = 0; k < n*m; ++k ) { filters_[k] = std::make_unique<filter>(sz, eta, mom, wd); } std::string filter_values; if ( opts.contains("filters") ) { filter_values = opts.require_as<std::string>("filters"); } else { size_t n_values = n*m*size_[0]*size_[1]*size_[2]; real * filters_raw = new real[n_values]; auto initf = get_initializator(opts); initf->initialize( filters_raw, n*m*size_[0]*size_[1]*size_[2] ); filter_values = std::string( reinterpret_cast<char*>(filters_raw), sizeof(real) * n_values ); delete [] filters_raw; } load_filters(filters_, size_, filter_values); int does_fft = options_.optional_as<int>("fft", "1"); auto repeat = options_.optional_as<ovec3i>("repeat", "1,1,1"); if ( size_ == vec3i::one ) does_fft = 0; for ( size_t i = 0, k = 0; i < n; ++i ) { for ( size_t j = 0; j < m; ++j, ++k ) { if ( repeat == ovec3i::one ) { if ( does_fft ) { edges_[k] = std::make_unique<fft_filter_edge> (in, i, out, j, tm_, stride, *filters_[k]); } else { edges_[k] = std::make_unique<filter_edge> (in, i, out, j, tm_, stride, *filters_[k]); } } else { if ( does_fft ) { edges_[k] = std::make_unique<fft_filter_ds_edge> (in, i, out, j, tm_, stride, repeat, *filters_[k]); } else { edges_[k] = std::make_unique<filter_ds_edge> (in, i, out, j, tm_, stride, repeat, *filters_[k]); } } } } }
transfer_nodes( size_t s, vec3i const & fsize, options const & op, task_manager & tm, size_t fwd_p, size_t bwd_p, bool is_out ) : nodes(s,fsize,op,tm,fwd_p,bwd_p,false,is_out) , biases_(s) , func_() , fwd_dispatch_(s) , bwd_dispatch_(s) , fwd_accumulators_(s) , bwd_accumulators_(s) , fs_(s) , fwd_done_(s) , waiter_(s) { for ( size_t i = 0; i < nodes::size(); ++i ) { fwd_accumulators_[i] = std::make_unique<forward_accumulator>(fsize); bwd_accumulators_[i] = std::make_unique<backward_accumulator>(fsize); } auto type = op.require_as<std::string>("type"); if ( type == "transfer" ) { func_ = get_transfer_function(op); // initialize biases real eta = op.optional_as<real>("eta", 0.0001); real mom = op.optional_as<real>("momentum", 0.0); real wd = op.optional_as<real>("weight_decay", 0.0); for ( auto& b: biases_ ) { b = std::make_unique<bias>(eta, mom, wd); } std::string bias_values; if ( op.contains("biases") ) { bias_values = op.require_as<std::string>("biases"); } else { real biases_raw[nodes::size()]; if ( op.contains("init") ) { auto initf = get_initializator(op); initf->initialize( biases_raw, nodes::size() ); } else { std::fill_n(biases_raw, nodes::size(), 0); } bias_values = std::string( reinterpret_cast<char*>(biases_raw), sizeof(real) * nodes::size() ); } load_biases(biases_, bias_values); } else { ZI_ASSERT(type=="sum"); } }