/* * Fills config with common backend info like config, group id */ static void fill_disabled_backend_config(rapidjson::Value &stat_value, rapidjson::Document::AllocatorType &allocator, const dnet_backend_info &config_backend) { rapidjson::Value backend_value(rapidjson::kObjectType); rapidjson::Value config_value(rapidjson::kObjectType); for (auto it = config_backend.options.begin(); it != config_backend.options.end(); ++it) { const dnet_backend_config_entry &entry = *it; rapidjson::Value tmp_val(entry.value_template.data(), allocator); config_value.AddMember(entry.entry->key, tmp_val, allocator); } backend_value.AddMember("config", config_value, allocator); stat_value.AddMember("backend", backend_value, allocator); }
/* * This function is called to fill in config values read from the config for non-enabled (yet) backends. * * If config template provides API for serializing parsed config values to json * it fills 'backend::config' section otherwise it uses unparsed values from original config * and fills 'backend::config_template'. * * After backend has been enabled, @fill_backend_backend() is called instead. */ static void fill_disabled_backend_config(rapidjson::Value &stat_value, rapidjson::Document::AllocatorType &allocator, const dnet_backend_info *config_backend) { rapidjson::Value backend_value(rapidjson::kObjectType); /* If config template provides API for serializing parsed config values to json - use it */ if (config_backend->config_template.to_json) { char *json_stat = NULL; size_t size = 0; dnet_config_backend config = config_backend->config_template; std::vector<char> data(config.size, '\0'); config.data = data.data(); config.log = config_backend->log.get(); for (auto it = config_backend->options.begin(); it != config_backend->options.end(); ++it) { const dnet_backend_config_entry &entry = *it; entry.entry->callback(&config, entry.entry->key, entry.value_template.data()); } config.to_json(&config, &json_stat, &size); if (json_stat && size) { rapidjson::Document config_value(&allocator); config_value.Parse<0>(json_stat); config_value.AddMember("group", config_backend->group, allocator); backend_value.AddMember("config", static_cast<rapidjson::Value&>(config_value), allocator); } free(json_stat); config.cleanup(&config); } else { rapidjson::Value config_value(rapidjson::kObjectType); for (auto it = config_backend->options.begin(); it != config_backend->options.end(); ++it) { const dnet_backend_config_entry &entry = *it; rapidjson::Value tmp_val(entry.value_template.data(), allocator); config_value.AddMember(entry.entry->key, tmp_val, allocator); } config_value.AddMember("group", config_backend->group, allocator); backend_value.AddMember("config_template", config_value, allocator); } stat_value.AddMember("backend", backend_value, allocator); }
void spgemm_rmerge(const AMatrix &A, const BMatrix &B, CMatrix &C) { typedef typename backend::value_type<CMatrix>::type Val; typedef ptrdiff_t Idx; Idx max_row_width = 0; #pragma omp parallel { Idx my_max = 0; #pragma omp for for(int i = 0; i < static_cast<Idx>(A.nrows); ++i) { Idx row_beg = A.ptr[i]; Idx row_end = A.ptr[i+1]; Idx row_width = 0; for(Idx j = row_beg; j < row_end; ++j) { Idx a_col = A.col[j]; row_width += B.ptr[a_col + 1] - B.ptr[a_col]; } my_max = std::max(my_max, row_width); } #pragma omp critical max_row_width = std::max(max_row_width, my_max); } #ifdef _OPENMP const int nthreads = omp_get_max_threads(); #else const int nthreads = 1; #endif std::vector< std::vector<Idx> > tmp_col(nthreads); std::vector< std::vector<Val> > tmp_val(nthreads); for(int i = 0; i < nthreads; ++i) { tmp_col[i].resize(3 * max_row_width); tmp_val[i].resize(2 * max_row_width); } C.set_size(A.nrows, B.ncols); C.ptr[0] = 0; #pragma omp parallel { #ifdef _OPENMP const int tid = omp_get_thread_num(); #else const int tid = 0; #endif Idx *t_col = &tmp_col[tid][0]; #pragma omp for for(Idx i = 0; i < static_cast<Idx>(A.nrows); ++i) { Idx row_beg = A.ptr[i]; Idx row_end = A.ptr[i+1]; C.ptr[i+1] = prod_row_width( A.col + row_beg, A.col + row_end, B.ptr, B.col, t_col, t_col + max_row_width, t_col + 2 * max_row_width ); } } C.set_nonzeros(C.scan_row_sizes()); #pragma omp parallel { #ifdef _OPENMP const int tid = omp_get_thread_num(); #else const int tid = 0; #endif Idx *t_col = tmp_col[tid].data(); Val *t_val = tmp_val[tid].data(); #pragma omp for for(Idx i = 0; i < static_cast<Idx>(A.nrows); ++i) { Idx row_beg = A.ptr[i]; Idx row_end = A.ptr[i+1]; prod_row( A.col + row_beg, A.col + row_end, A.val + row_beg, B.ptr, B.col, B.val, C.col + C.ptr[i], C.val + C.ptr[i], t_col, t_val, t_col + max_row_width, t_val + max_row_width ); } } }
std::vector< std::string > square_parenthetical_split(std::string const &val, const char separator, std::string const &left, std::string const &right,const int flags) { std::vector< std::string > res; std::vector<char> part; bool in_parenthesis = false; std::vector<std::string::const_iterator> square_left; std::vector<std::string::const_iterator> square_right; std::vector< std::string > square_expansion; std::string lp=left; std::string rp=right; std::string::const_iterator i1 = val.begin(); std::string::const_iterator i2; std::string::const_iterator j1; if (flags & STRIP_SPACES) { while (i1 != val.end() && portable_isspace(*i1)) ++i1; } i2=i1; j1=i1; if (i1 == val.end()) return res; if (!separator) { ERR_GENERAL << "Separator must be specified for square bracket split funtion.\n"; return res; } if(left.size()!=right.size()){ ERR_GENERAL << "Left and Right Parenthesis lists not same length\n"; return res; } while (true) { if(i2 == val.end() || (!in_parenthesis && *i2 == separator)) { //push back square contents size_t size_square_exp = 0; for (size_t i=0; i < square_left.size(); i++) { std::string tmp_val(square_left[i]+1,square_right[i]); std::vector< std::string > tmp = split(tmp_val); std::vector<std::string>::const_iterator itor = tmp.begin(); for(; itor != tmp.end(); ++itor) { size_t found_tilde = (*itor).find_first_of('~'); if (found_tilde == std::string::npos) { size_t found_asterisk = (*itor).find_first_of('*'); if (found_asterisk == std::string::npos) { std::string tmp = (*itor); square_expansion.push_back(strip(tmp)); } else { //'*' multiple expansion std::string s_begin = (*itor).substr(0,found_asterisk); s_begin = strip(s_begin); std::string s_end = (*itor).substr(found_asterisk+1); s_end = strip(s_end); for (int ast=atoi(s_end.c_str()); ast>0; --ast) square_expansion.push_back(s_begin); } } else { //expand number range std::string s_begin = (*itor).substr(0,found_tilde); s_begin = strip(s_begin); int begin = atoi(s_begin.c_str()); size_t padding = 0; while (padding<s_begin.size() && s_begin[padding]=='0') { padding++; } std::string s_end = (*itor).substr(found_tilde+1); s_end = strip(s_end); int end = atoi(s_end.c_str()); if (padding==0) { while (padding<s_end.size() && s_end[padding]=='0') { padding++; } } int increment = (end >= begin ? 1 : -1); end+=increment; //include end in expansion for (int k=begin; k!=end; k+=increment) { std::string pb = boost::lexical_cast<std::string>(k); for (size_t p=pb.size(); p<=padding; p++) pb = std::string("0") + pb; square_expansion.push_back(pb); } } } if (i*square_expansion.size() != (i+1)*size_square_exp ) { std::string tmp(i1, i2); ERR_GENERAL << "Square bracket lengths do not match up: "+tmp+"\n"; return res; } size_square_exp = square_expansion.size(); } //combine square contents and rest of string for comma zone block size_t j = 0; size_t j_max = 0; if (square_left.size() != 0) j_max = square_expansion.size() / square_left.size(); do { j1 = i1; std::string new_val; for (size_t i=0; i < square_left.size(); i++) { std::string tmp_val(j1, square_left[i]); new_val.append(tmp_val); size_t k = j+i*j_max; if (k < square_expansion.size()) new_val.append(square_expansion[k]); j1 = square_right[i]+1; } std::string tmp_val(j1, i2); new_val.append(tmp_val); if (flags & STRIP_SPACES) strip_end(new_val); if (!(flags & REMOVE_EMPTY) || !new_val.empty()) res.push_back(new_val); j++; } while (j<j_max); if (i2 == val.end()) //escape loop break; ++i2; if (flags & STRIP_SPACES) { //strip leading spaces while (i2 != val.end() && portable_isspace(*i2)) ++i2; } i1=i2; square_left.clear(); square_right.clear(); square_expansion.clear(); continue; } if(!part.empty() && *i2 == part.back()) { part.pop_back(); if (*i2 == ']') square_right.push_back(i2); if (part.empty()) in_parenthesis = false; ++i2; continue; } bool found=false; for(size_t i=0; i < lp.size(); i++) { if (*i2 == lp[i]){ if (*i2 == '[') square_left.push_back(i2); ++i2; part.push_back(rp[i]); found=true; break; } } if(!found){ ++i2; } else in_parenthesis = true; } if(!part.empty()){ ERR_GENERAL << "Mismatched parenthesis:\n"<<val<<"\n";; } return res; }