<commit_before>/**
 * @file partial_reduce_internal.h
 *
 * Internal implementation of partial reduction evaluation
 *
 * @author <NAME>
 */

#ifdef _MSC_VER
#pragma once
#endif

#ifndef LIGHTMAT_PARTIAL_REDUCE_INTERNAL_H_
#define LIGHTMAT_PARTIAL_REDUCE_INTERNAL_H_

#include "matrix_reduce_internal.h"

namespace lmat { namespace detail {

	template<typename KerCate> struct colwise_reduce_internal;
	template<typename KerCate> struct rowwise_reduce_internal;


	template<>
	struct colwise_reduce_internal<scalar_kernel_t>
	{
		template<class Fun, class Arg, class Dst>
		inline
		static void eval(const Fun& fun, const Arg& arg, Dst& dst)
		{
			typedef matrix_visit_setting<
					percol_vis,
					scalar_kernel_t,
					ct_rows<Arg>::value,
					binary_ct_cols<Arg, Dst>::value> setting_t;

			const index_t m = arg.nrows();
			const index_t n = arg.ncolumns();

			typedef typename matrix_vismap<Arg, setting_t>::type visitor_t;
			visitor_t visitor(arg);

			for (index_t j = 0; j < n; ++j)
			{
				typename matrix_visitor_state<visitor_t>::type s = visitor.col_state(j);

				dst.elem(0, j) = single_vec_reduce<
							ct_rows<Arg>::value,
							scalar_kernel_t>::eval(fun, m, visitor, s);
			}
		}
	};



	template<int CTLen, typename KerCate> struct accum_col;

	template<int CTLen>
	struct accum_col<CTLen, scalar_kernel_t>
	{
		template<class Fun, class Visitor, class State>
		LMAT_ENSURE_INLINE
		static void eval(const Fun& fun, const index_t, const Visitor& vis, const State& s,
				typename Fun::result_type *pd)
		{
			for (index_t i = 0; i < CTLen; ++i)
			{
				pd[i] = fun(pd[i], vis.get_scalar(i, s));
			}
		}

		template<class Fun, class Visitor, class State>
		LMAT_ENSURE_INLINE
		static void init_eval(const Fun& fun, const index_t, const Visitor& vis, const State& s,
				typename Fun::result_type *pd)
		{
			for (index_t i = 0; i < CTLen; ++i)
			{
				pd[i] = fun(vis.get_scalar(i, s));
			}
		}

		template<class Fun>
		LMAT_ENSURE_INLINE
		static void empty_eval(const Fun& fun, const index_t, typename Fun::result_type *pd)
		{
			for (index_t i = 0; i < CTLen; ++i)
			{
				pd[i] = fun();
			}
		}
	};

	template<>
	struct accum_col<0, scalar_kernel_t>
	{
		template<class Fun, class Visitor, typename State>
		LMAT_ENSURE_INLINE
		static void eval(const Fun& fun, const index_t m, const Visitor& vis, const State& s,
				typename Fun::result_type *pd)
		{
			for (index_t i = 0; i < m; ++i)
			{
				pd[i] = fun(pd[i], vis.get_scalar(i, s));
			}
		}

		template<class Fun, class Visitor, typename State>
		LMAT_ENSURE_INLINE
		static void init_eval(const Fun& fun, const index_t m, const Visitor& vis, const State& s,
				typename Fun::result_type *pd)
		{
			for (index_t i = 0; i < m; ++i)
			{
				pd[i] = fun(vis.get_scalar(i, s));
			}
		}

		template<class Fun>
		LMAT_ENSURE_INLINE
		static void empty_eval(const Fun& fun, const index_t m, typename Fun::result_type *pd)
		{
			for (index_t i = 0; i < m; ++i)
			{
				pd[i] = fun();
			}
		}
	};

	template<>
	struct accum_col<1, scalar_kernel_t>
	{
		template<class Fun, class Visitor, typename State>
		LMAT_ENSURE_INLINE
		static void eval(const Fun& fun, const index_t, const Visitor& vis, const State& s,
				typename Fun::result_type *pd)
		{
			pd[0] = fun(pd[0], vis.get_scalar(0, s));
		}

		template<class Fun, class Visitor, typename State>
		LMAT_ENSURE_INLINE
		static void init_eval(const Fun& fun, const index_t, const Visitor& vis, const State& s,
				typename Fun::result_type *pd)
		{
			pd[0] = fun(vis.get_scalar(0, s));
		}

		template<class Fun>
		LMAT_ENSURE_INLINE
		static void empty_eval(const Fun& fun, const index_t, typename Fun::result_type *pd)
		{
			pd[0] = fun();
		}
	};


	template<>
	struct rowwise_reduce_internal<scalar_kernel_t>
	{
		template<class Fun, class Arg, class Dst>
		inline
		static void eval(const Fun& fun, const Arg& arg, Dst& dst)
		{
			typedef accum_col<ct_rows<Arg>::value, scalar_kernel_t> accum_t;

			typedef matrix_visit_setting<
					percol_vis,
					scalar_kernel_t,
					binary_ct_rows<Arg, Dst>::value,
					ct_cols<Arg>::value> setting_t;

			typedef typename matrix_vismap<Arg, setting_t>::type visitor_t;
			typedef typename matrix_visitor_state<visitor_t>::type state_t;

			typename matrix_traits<Dst>::value_type* pd = dst.ptr_data();

			const index_t m = arg.nrows();
			const index_t n = arg.ncolumns();

			if (n > 0)
			{
				visitor_t visitor(arg);

				state_t s0 = visitor.col_state(0);
				accum_t::init_eval(fun, m, visitor, s0, pd);

				if (n > 1)
				{
					for (index_t j = 1; j < n; ++j)
					{
						state_t s = visitor.col_state(j);
						accum_t::eval(fun, m, visitor, s, pd);
					}
				}
			}
			else
			{
				accum_t::empty_eval(fun, m, pd);
			}

		}
	};


} }

#endif<commit_msg>revise the internal of partial reduce<commit_after>/**
 * @file partial_reduce_internal.h
 *
 * Internal implementation of partial reduction evaluation
 *
 * @author <NAME>
 */

#ifdef _MSC_VER
#pragma once
#endif

#ifndef LIGHTMAT_PARTIAL_REDUCE_INTERNAL_H_
#define LIGHTMAT_PARTIAL_REDUCE_INTERNAL_H_

#include <light_mat/matexpr/matrix_access_base.h>
#include <light_mat/matrix/matrix_fill.h>

#include "matrix_reduce_internal.h"

namespace lmat { namespace detail {

	template<typename KerCate> struct colwise_reduce_internal;
	template<typename InterT, typename KerCate> struct rowwise_reduce_internal;


	template<>
	struct colwise_reduce_internal<scalar_kernel_t>
	{
		template<class Fun, class Arg, class Dst>
		static void eval(const Fun& fun, const Arg& a, Dst& dst)
		{
			typedef typename matrix_traits<Dst>::value_type RT;
			typedef typename macc_accessor_map<Arg, percol_macc, scalar_kernel_t>::type accessor_t;
			typedef typename percol_macc_state_map<accessor_t>::type col_state_t;

			const index_t m = a.nrows();
			const index_t n = a.ncolumns();

			accessor_t acc(a);

			if (m > 0)
			{
				if (m == 1)
				{
					for (index_t j = 0; j < n; ++j)
					{
						dst(0, j) = fun.get(
								fun.transform(acc.get_scalar(0, acc.col_state(j))), 1);
					}
				}
				else
				{
					typedef vec_reduce<RT, ct_rows<Arg>::value, scalar_kernel_t> vimpl_t;
					for (index_t j = 0; j < n; ++j)
					{
						dst(0, j) = fun.get(vimpl_t::eval_s(fun, m, acc, acc.col_state(j)), m);
					}
				}
			}
			else
			{
				if (n > 0)
					fill(dst, fun.empty_value());
			}
		}


		template<class Fun, class Arg1, class Arg2, class Dst>
		static void eval(const Fun& fun, const Arg1& a1, const Arg2& a2, Dst& dst)
		{
			typedef typename matrix_traits<Dst>::value_type RT;
			typedef typename macc_accessor_map<Arg1, percol_macc, scalar_kernel_t>::type accessor1_t;
			typedef typename macc_accessor_map<Arg2, percol_macc, scalar_kernel_t>::type accessor2_t;
			typedef typename percol_macc_state_map<accessor1_t>::type col_state1_t;
			typedef typename percol_macc_state_map<accessor2_t>::type col_state2_t;

			const index_t m = a1.nrows();
			const index_t n = a2.ncolumns();

			accessor1_t acc1(a1);
			accessor2_t acc2(a2);

			if (m > 0)
			{
				if (m == 1)
				{
					for (index_t j = 0; j < n; ++j)
					{
						dst(0, j) = fun.get(
								fun.transform(
										acc1.get_scalar(0, acc1.col_state(j)),
										acc2.get_scalar(0, acc2.col_state(j))), 1);
					}
				}
				else
				{
					typedef vec_reduce<RT, binary_ct_rows<Arg1, Arg2>::value, scalar_kernel_t> vimpl_t;
					for (index_t j = 0; j < n; ++j)
					{
						dst(0, j) = fun.get(vimpl_t::eval_s(fun, m,
								acc1, acc1.col_state(j), acc2, acc2.col_state(j)), m);
					}
				}
			}
			else
			{
				if (n > 0)
					fill(dst, fun.empty_value());
			}
		}
	};


	template<int M, typename ColStateT, typename InterT, typename T>
	struct rowwise_reduce_mcol_impl
	{
		template<class Fun, class Accessor, class Dst>
		static void eval(const Fun& fun, const Accessor& acc,
				index_t m, index_t n,
				const T *pd, index_t rs, index_t cs)
		{
			dense_col<InterT, M> mvs(m);

			ColStateT s0 = acc.col_state(0);
			for (index_t i = 0; i < m; ++i)
			{
				mvs[i] = fun.transform(acc.get_scalar(i, s0));
			}

			for (index_t j = 1; j < n; ++j, pd += cs)
			{
				ColStateT s = acc.col_state(j);
				for (index_t i = 0; i < m; ++i)
				{
					mvs[i] = fun.combine(mvs[i], fun.transform(acc.get_scalar(i, s)));
				}
			}

			if (rs == 1)
			{
				for (index_t i = 0; i < m; ++i)
				{
					pd[i] = fun.get(mvs[i], n);
				}
			}
			else
			{
				for (index_t i = 0; i < m; ++i)
				{
					pd[i * rs] = fun.get(mvs[i], n);
				}
			}
		}
	};


	template<int M, typename ColStateT, typename T>
	struct rowwise_reduce_mcol_impl<M, ColStateT, T, T>
	{
		template<class Fun, class Accessor, class Dst>
		static void eval(const Fun& fun, const Accessor& acc,
				index_t m, index_t n,
				const T *pd, index_t rs, index_t cs)
		{

			if (rs == 1)
			{
				ColStateT s0 = acc.col_state(0);

				for (index_t i = 0; i < m; ++i)
				{
					pd[i] = fun.transform(acc.get_scalar(i, s0));
				}

				for (index_t j = 1; j < n; ++j)
				{
					ColStateT s = acc.col_state(j);
					for (index_t i = 0; i < m; ++i)
					{
						pd[i] = fun.combine(pd[i], fun.transform(acc.get_scalar(i, s)));
					}
				}

				for (index_t i = 0; i < m; ++i)
				{
					pd[i] = fun.get(pd[i], n);
				}
			}
			else
			{
				ColStateT s0 = acc.col_state(0);

				for (index_t i = 0; i < m; ++i)
				{
					pd[i * rs] = fun.transform(acc.get_scalar(i, s0));
				}

				for (index_t j = 1; j < n; ++j)
				{
					ColStateT s = acc.col_state(j);
					for (index_t i = 0; i < m; ++i)
					{
						pd[i * rs] = fun.combine(pd[i * rs], fun.transform(acc.get_scalar(i, s)));
					}
				}

				for (index_t i = 0; i < m; ++i)
				{
					pd[i * rs] = fun.get(pd[i * rs], n);
				}
			}

		}
	};




	template<typename InterT>
	struct rowwise_reduce_internal<InterT, scalar_kernel_t>
	{
		template<class Fun, class Arg, class Dst>
		static void eval(const Fun& fun, const Arg& a, Dst& dst)
		{
			typedef typename matrix_traits<Dst>::value_type RT;
			typedef typename macc_accessor_map<Arg, percol_macc, scalar_kernel_t>::type accessor_t;
			typedef typename percol_macc_state_map<accessor_t>::type col_state_t;
			typedef rowwise_reduce_mcol_impl<binary_ct_rows<Arg, Dst>::value, col_state_t, InterT, RT> mcol_impl_t;

			const index_t m = a.nrows();
			const index_t n = a.ncolumns();

			accessor_t acc(a);
			RT *pd = dst.ptr_data();


			if (n > 0)
			{
				if (n == 1)
				{
					col_state_t s0 = acc.col_state(0);

					if (m == 1)
					{
						*pd = fun.get(fun.transform(acc.get_scalar(0, s0)));
					}
					else
					{
						const index_t rs = dst.row_stride();
						if (rs == 1)
						{
							for (index_t i = 0; i < m; ++i)
							{
								pd[i] = fun.get(fun.transform(acc.get_scalar(i, s0)));
							}
						}
						else
						{
							for (index_t i = 0; i < m; ++i)
							{
								pd[i * rs] = fun.get(fun.transform(acc.get_scalar(i, s0)));
							}
						}
					}
				}
				else
				{
					const index_t cs = dst.col_stride();

					if (m == 1)
					{
						InterT mv = fun.transform(acc.get_scalar(0, acc.col_state(0)));
						for (index_t j = 1; j < n; ++j)
						{
							mv = fun.combine(mv, acc.get_scalar(0, acc.col_state(j)));
						}
					}
					else
					{
						mcol_impl_t::eval(fun, acc, m, n, pd, dst.row_stride(), dst.col_stride());
					}
				}
			}
			else
			{
				if (m > 0)
					fill(dst, fun.empty_value());
			}
		}
	};


} }

#endif
{'fraction_non_alphanumeric': 0.13694659170765988, 'fraction_numerical': 0.010101897399859451, 'mean_word_length': 2.919104991394148, 'pattern_counts': {'":': 0, '<': 106, '<?xml version=': 0, '>': 86, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3947521', 'n_tokens_mistral': 5651, 'n_tokens_neox': 4494, 'n_words': 1063}