T check_projection_accurate(const arma::Mat<T>& data, const armapca::pca_result<T>& result) { EXPECTS(data.n_rows >= 2); EXPECTS(data.n_cols >= 1); EXPECTS(result.eigenvectors.n_cols >= 1); const arma::Mat<T> diff = ((data * result.eigenvectors) * arma::trans(result.eigenvectors)) - data; return T {1} - arma::sum(arma::sum(arma::abs(diff) )) / diff.n_elem; }
std::vector<armapca::pca_result<T>> pca_bootstrap(const arma::Mat<T>& data, bool compute_eigenvectors, std::size_t n_bootstraps, std::size_t random_seed) { EXPECTS(data.n_rows >= 2); EXPECTS(data.n_cols >= 1); std::vector<armapca::pca_result<T>> result(n_bootstraps); std::mt19937 gen{random_seed}; for (std::size_t i=0; i < n_bootstraps; ++i) { const auto shuffled = armapca::shuffled_matrix(data, &gen); result[i] = armapca::pca(shuffled, compute_eigenvectors); } return result; }
armapca::pca_result<T> pca(const arma::Mat<T>& data, bool compute_eigenvectors) { EXPECTS(data.n_rows >= 2); EXPECTS(data.n_cols >= 1); const auto n_vars = data.n_cols; armapca::pca_result<T> result; arma::Mat<T> eigvec; if (compute_eigenvectors) { result.eigenvectors.set_size(n_vars, n_vars); eigvec.set_size(n_vars, n_vars); } result.eigenvalues.set_size(n_vars); arma::Col<T> eigval(n_vars); const auto cov_mat = armapca::covariance_matrix(data); if (compute_eigenvectors) { arma::eig_sym(eigval, eigvec, cov_mat); } else { arma::eig_sym(eigval, cov_mat); } const arma::uvec indices = arma::sort_index(eigval, 1); for (std::size_t i=0; i < n_vars; ++i) { result.eigenvalues(i) = eigval(indices(i)); } if (compute_eigenvectors) { for (std::size_t i=0; i < n_vars; ++i) { result.eigenvectors.col(i) = eigvec.col(indices(i)); } armapca::enforce_positive_sign_by_column(&result.eigenvectors); } result.energy = arma::sum(result.eigenvalues); result.eigenvalues *= T {1} / result.energy; return result; }
u64 write(const void* buffer, u64 count) override { // TODO (call WriteFile multiple times if count is too big) const int size = ::narrow<int>(count, "Too big count" HERE); EXPECTS(size >= 0); DWORD nwritten; if (!WriteFile(m_handle, buffer, size, &nwritten, NULL)) { throw fmt::exception("Win32 error: %u." HERE, GetLastError()); } return nwritten; }
u32 get_vertex_type_size_on_host(vertex_base_type type, u32 size) { switch (type) { case vertex_base_type::s1: case vertex_base_type::s32k: switch (size) { case 1: case 2: case 4: return sizeof(u16) * size; case 3: return sizeof(u16) * 4; } throw EXCEPTION("Wrong vector size"); case vertex_base_type::f: return sizeof(f32) * size; case vertex_base_type::sf: switch (size) { case 1: case 2: case 4: return sizeof(f16) * size; case 3: return sizeof(f16) * 4; } throw EXCEPTION("Wrong vector size"); case vertex_base_type::ub: switch (size) { case 1: case 2: case 4: return sizeof(u8) * size; case 3: return sizeof(u8) * 4; } throw EXCEPTION("Wrong vector size"); case vertex_base_type::cmp: return sizeof(u16) * 4; case vertex_base_type::ub256: EXPECTS(size == 4); return sizeof(u8) * 4; } throw EXCEPTION("RSXVertexData::GetTypeSize: Bad vertex data type (%d)!", type); }
void thread::do_internal_task() { if (m_internal_tasks.empty()) { std::this_thread::sleep_for(1ms); } else { EXPECTS(0); //std::lock_guard<std::mutex> lock{ m_mtx_task }; //internal_task_entry &front = m_internal_tasks.front(); //if (front.callback()) //{ // front.promise.set_value(); // m_internal_tasks.pop_front(); //} } }
void CgBinaryDisasm::AddCodeAsm(const std::string& code) { EXPECTS(m_opcode < 70); std::string op_name = ""; if (dst.dest_reg == 63) { m_dst_reg_name = fmt::format("RC%s, ", GetMask().c_str()); op_name = rsx_fp_op_names[m_opcode] + "XC"; } else { m_dst_reg_name = fmt::format("%s%d%s, ", dst.fp16 ? "H" : "R", dst.dest_reg, GetMask().c_str()); op_name = rsx_fp_op_names[m_opcode] + std::string(dst.fp16 ? "H" : "R"); } switch (m_opcode) { case RSX_FP_OPCODE_BRK: case RSX_FP_OPCODE_CAL: case RSX_FP_OPCODE_FENCT: case RSX_FP_OPCODE_FENCB: case RSX_FP_OPCODE_IFE: case RSX_FP_OPCODE_KIL: case RSX_FP_OPCODE_LOOP: case RSX_FP_OPCODE_NOP: case RSX_FP_OPCODE_REP: case RSX_FP_OPCODE_RET: m_dst_reg_name = ""; op_name = rsx_fp_op_names[m_opcode] + std::string(dst.fp16 ? "H" : "R"); break; default: break; } m_arb_shader += (op_name + " " + m_dst_reg_name + FormatDisAsm(code) + ";" + "\n"); }
std::shared_ptr<fs::device_base> fs::set_virtual_device(const std::string& name, const std::shared_ptr<device_base>& device) { EXPECTS(name.size() > 2 && name[0] == '/' && name[1] == '/' && name.find('/', 2) == -1); return get_device_manager().set_device(name, device); }
arma::Mat<T> covariance_matrix(const arma::Mat<T>& matrix) { EXPECTS(matrix.n_rows >= 2); EXPECTS(matrix.n_cols >= 1); return (arma::trans(matrix) * matrix) * (T {1} / (matrix.n_rows - 1)); }
void CgBinaryDisasm::TaskFP() { m_size = 0; u32* data = (u32*)&m_buffer[m_offset]; EXPECTS((m_buffer_size - m_offset) % sizeof(u32) == 0); for (u32 i = 0; i < (m_buffer_size - m_offset) / sizeof(u32); i++) { data[i] = se_storage<u32>::swap(data[i]); // WTF, cannot use be_t<> there? } enum { FORCE_NONE, FORCE_SCT, FORCE_SCB }; int forced_unit = FORCE_NONE; while (true) { for (auto found = std::find(m_end_offsets.begin(), m_end_offsets.end(), m_size); found != m_end_offsets.end(); found = std::find(m_end_offsets.begin(), m_end_offsets.end(), m_size)) { m_end_offsets.erase(found); m_arb_shader += "ENDIF;\n"; } for (auto found = std::find(m_loop_end_offsets.begin(), m_loop_end_offsets.end(), m_size); found != m_loop_end_offsets.end(); found = std::find(m_loop_end_offsets.begin(), m_loop_end_offsets.end(), m_size)) { m_loop_end_offsets.erase(found); m_arb_shader += "ENDLOOP;\n"; } for (auto found = std::find(m_else_offsets.begin(), m_else_offsets.end(), m_size); found != m_else_offsets.end(); found = std::find(m_else_offsets.begin(), m_else_offsets.end(), m_size)) { m_else_offsets.erase(found); m_arb_shader += "ELSE;\n"; } dst.HEX = GetData(data[0]); src0.HEX = GetData(data[1]); src1.HEX = GetData(data[2]); src2.HEX = GetData(data[3]); m_step = 4 * sizeof(u32); m_opcode = dst.opcode | (src1.opcode_is_branch << 6); auto SCT = [&]() { switch (m_opcode) { case RSX_FP_OPCODE_ADD: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_DIV: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_DIVSQ: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_DP2: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_DP3: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_DP4: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_DP2A: AddCodeAsm("$0, $1, $2"); break; case RSX_FP_OPCODE_MAD: AddCodeAsm("$0, $1, $2"); break; case RSX_FP_OPCODE_MAX: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_MIN: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_MOV: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_MUL: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_RCP: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_RSQ: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_SEQ: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_SFL: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_SGE: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_SGT: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_SLE: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_SLT: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_SNE: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_STR: AddCodeAsm("$0, $1"); break; default: return false; } return true; }; auto SCB = [&]() { switch (m_opcode) { case RSX_FP_OPCODE_ADD: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_COS: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_DP2: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_DP3: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_DP4: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_DP2A: AddCodeAsm("$0, $1, $2"); break; case RSX_FP_OPCODE_DST: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_REFL: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_EX2: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_FLR: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_FRC: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_LIT: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_LIF: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_LRP: AddCodeAsm("# WARNING"); break; case RSX_FP_OPCODE_LG2: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_MAD: AddCodeAsm("$0, $1, $2"); break; case RSX_FP_OPCODE_MAX: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_MIN: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_MOV: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_MUL: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_PK2: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_PK4: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_PK16: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_PKB: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_PKG: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_SEQ: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_SFL: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_SGE: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_SGT: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_SIN: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_SLE: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_SLT: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_SNE: AddCodeAsm("$0, $1"); break; case RSX_FP_OPCODE_STR: AddCodeAsm("$0, $1"); break; default: return false; } return true; }; auto TEX_SRB = [&]() { switch (m_opcode) { case RSX_FP_OPCODE_DDX: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_DDY: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_NRM: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_BEM: AddCodeAsm("# WARNING"); break; case RSX_FP_OPCODE_TEX: AddCodeAsm("$0, $t"); break; case RSX_FP_OPCODE_TEXBEM: AddCodeAsm("# WARNING"); break; case RSX_FP_OPCODE_TXP: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_TXPBEM: AddCodeAsm("# WARNING"); break; case RSX_FP_OPCODE_TXD: AddCodeAsm("$0, $1, $t"); break; case RSX_FP_OPCODE_TXB: AddCodeAsm("$0, $t"); break; case RSX_FP_OPCODE_TXL: AddCodeAsm("$0, $t"); break; case RSX_FP_OPCODE_UP2: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_UP4: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_UP16: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_UPB: AddCodeAsm("$0"); break; case RSX_FP_OPCODE_UPG: AddCodeAsm("$0"); break; default: return false; } return true; }; auto SIP = [&]() { switch (m_opcode) { case RSX_FP_OPCODE_BRK: AddCodeAsm("$cond"); break; case RSX_FP_OPCODE_CAL: AddCodeAsm("$cond"); break; case RSX_FP_OPCODE_FENCT: AddCodeAsm(""); break; case RSX_FP_OPCODE_FENCB: AddCodeAsm(""); break; case RSX_FP_OPCODE_IFE: { m_else_offsets.push_back(src1.else_offset << 2); m_end_offsets.push_back(src2.end_offset << 2); AddCodeAsm("($cond)"); } break; case RSX_FP_OPCODE_LOOP: { if (!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt) { AddCodeAsm(fmt::format("{ %u, %u, %u }", src1.end_counter, src1.init_counter, src1.increment)); } else { m_loop_end_offsets.push_back(src2.end_offset << 2); AddCodeAsm(fmt::format("{ %u, %u, %u }", src1.end_counter, src1.init_counter, src1.increment)); } } break; case RSX_FP_OPCODE_REP: { if (!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt) { m_arb_shader += "# RSX_FP_OPCODE_REP_1\n"; } else { m_end_offsets.push_back(src2.end_offset << 2); m_arb_shader += "# RSX_FP_OPCODE_REP_2\n"; } } break; case RSX_FP_OPCODE_RET: AddCodeAsm("$cond"); break; default: return false; } return true; }; switch (m_opcode) { case RSX_FP_OPCODE_NOP: AddCodeAsm(""); break; case RSX_FP_OPCODE_KIL: AddCodeAsm("$cond"); break; default: if (forced_unit == FORCE_NONE) { if (SIP()) break; if (SCT()) break; if (TEX_SRB()) break; if (SCB()) break; } else if (forced_unit == FORCE_SCT) { forced_unit = FORCE_NONE; if (SCT()) break; } else if (forced_unit == FORCE_SCB) { forced_unit = FORCE_NONE; if (SCB()) break; } LOG_ERROR(RSX, "Unknown/illegal instruction: 0x%x (forced unit %d)", m_opcode, forced_unit); break; } m_size += m_step; if (dst.end) { m_arb_shader.pop_back(); m_arb_shader += " # last inctruction\nEND\n"; break; } ENSURES(m_step % sizeof(u32) == 0); data += m_step / sizeof(u32); } }