<commit_before>#pragma once
#include "expression.hpp"
#include "expression_node.hpp"

namespace nnk
{

	template <class T>
	class matrix_product_expression_node : public expression_node<T>
	{
	private:

		typedef expression_node<T> base_type;

	public:

		typedef typename base_type::scalar_type scalar_type;
		typedef typename base_type::tensor_type tensor_type;
		typedef typename base_type::node_pointer node_pointer;

		matrix_product_expression_node(
			const node_pointer& lhs,
			const node_pointer& rhs,
			std::size_t lhs_rows,
			std::size_t lhs_cols,
			std::size_t rhs_rows,
			std::size_t rhs_cols)
			: lhs_(lhs)
			, rhs_(rhs)
			, lhs_rows_(lhs_rows)
			, lhs_cols_(lhs_cols)
			, rhs_cols_(rhs_cols)
			, lhs_size_(lhs_rows * lhs_cols)
			, rhs_size_(rhs_rows * rhs_cols)
			, output_size_(lhs_rows * rhs_cols)
		{
			BOOST_ASSERT(lhs_cols == rhs_rows);
		}

		virtual bool is_branch() override
		{
			return true;
		}

		virtual void forward() override
		{
			if (lhs_->output().size() == lhs_size_ &&
				rhs_->output().size() == rhs_size_)
			{
				if (this->output().size() != output_size_)
					this->output().resize(output_size_);

				forward_impl(
					&lhs_->output()[0],
					&rhs_->output()[0],
					&this->output()[0]);
			}
			else if (lhs_->output().size() == lhs_size_)
			{
				BOOST_ASSERT(rhs_->output().size() % rhs_size_ == 0);

				std::size_t count = rhs_->output().size() / rhs_size_;
				std::size_t total_output_size = output_size_ * count;

				if (this->output().size() != total_output_size)
					this->output().resize(total_output_size);

				std::size_t rhs_index = 0;
				std::size_t output_index = 0;

				for (std::size_t i = 0; i < count; ++i)
				{
					forward_impl(
						&lhs_->output()[0],
						&rhs_->output()[rhs_index],
						&this->output()[output_index]);

					rhs_index += rhs_size_;
					output_index += output_size_;
				}
			}
			else if (rhs_->output().size() == rhs_size_)
			{
				BOOST_ASSERT(lhs_->output().size() % lhs_size_ == 0);

				std::size_t count = lhs_->output().size() / lhs_size_;
				std::size_t total_output_size = output_size_ * count;

				if (this->output().size() != total_output_size)
					this->output().resize(total_output_size);

				std::size_t lhs_index = 0;
				std::size_t output_index = 0;

				for (std::size_t i = 0; i < count; ++i)
				{
					forward_impl(
						&lhs_->output()[lhs_index],
						&rhs_->output()[0],
						&this->output()[output_index]);

					lhs_index += lhs_size_;
					output_index += output_size_;
				}
			}
			else
			{
				BOOST_ASSERT(false);
			}
		}

		virtual void backward() override
		{
			if (lhs_->output().size() == lhs_size_ &&
				rhs_->output().size() == rhs_size_)
			{
				backward_impl(
					&lhs_->output_grad()[0],
					&rhs_->output_grad()[0],
					&lhs_->output()[0],
					&rhs_->output()[0],
					&this->output_grad()[0]);
			}
			else if (lhs_->output().size() == lhs_size_)
			{
				std::size_t count = rhs_->output().size() / rhs_size_;
				std::size_t total_output_size = output_size_ * count;

				std::size_t rhs_index = 0;
				std::size_t output_index = 0;

				for (std::size_t i = 0; i < count; ++i)
				{
					backward_impl(
						&lhs_->output_grad()[0],
						&rhs_->output_grad()[rhs_index],
						&lhs_->output()[0],
						&rhs_->output()[rhs_index],
						&this->output_grad()[output_index]);

					rhs_index += rhs_size_;
					output_index += output_size_;
				}
			}
			else if (rhs_->output().size() == rhs_size_)
			{
				std::size_t count = lhs_->output().size() / lhs_size_;
				std::size_t total_output_size = output_size_ * count;

				std::size_t lhs_index = 0;
				std::size_t output_index = 0;

				for (std::size_t i = 0; i < count; ++i)
				{
					backward_impl(
						&lhs_->output_grad()[lhs_index],
						&rhs_->output_grad()[0],
						&lhs_->output()[lhs_index],
						&rhs_->output()[0],
						&this->output_grad()[output_index]);

					lhs_index += lhs_size_;
					output_index += output_size_;
				}
			}
			else
			{
				BOOST_ASSERT(false);
			}
		}

		virtual void enumerate_children(const std::function<void(expression_node_base*)>& callback) override
		{
			callback(lhs_.get());<commit_msg>Fix warnings on clang<commit_after>#pragma once
#include "expression.hpp"
#include "expression_node.hpp"

namespace nnk
{

	template <class T>
	class matrix_product_expression_node : public expression_node<T>
	{
	private:

		typedef expression_node<T> base_type;

	public:

		typedef typename base_type::scalar_type scalar_type;
		typedef typename base_type::tensor_type tensor_type;
		typedef typename base_type::node_pointer node_pointer;

		matrix_product_expression_node(
			const node_pointer& lhs,
			const node_pointer& rhs,
			std::size_t lhs_rows,
			std::size_t lhs_cols,
			std::size_t rhs_rows,
			std::size_t rhs_cols)
			: lhs_(lhs)
			, rhs_(rhs)
			, lhs_rows_(lhs_rows)
			, lhs_cols_(lhs_cols)
			, rhs_cols_(rhs_cols)
			, lhs_size_(lhs_rows * lhs_cols)
			, rhs_size_(rhs_rows * rhs_cols)
			, output_size_(lhs_rows * rhs_cols)
		{
			BOOST_ASSERT(lhs_cols == rhs_rows);
		}

		virtual bool is_branch() override
		{
			return true;
		}

		virtual void forward() override
		{
			if (lhs_->output().size() == lhs_size_ &&
				rhs_->output().size() == rhs_size_)
			{
				if (this->output().size() != output_size_)
					this->output().resize(output_size_);

				forward_impl(
					&lhs_->output()[0],
					&rhs_->output()[0],
					&this->output()[0]);
			}
			else if (lhs_->output().size() == lhs_size_)
			{
				BOOST_ASSERT(rhs_->output().size() % rhs_size_ == 0);

				std::size_t count = rhs_->output().size() / rhs_size_;
				std::size_t total_output_size = output_size_ * count;

				if (this->output().size() != total_output_size)
					this->output().resize(total_output_size);

				std::size_t rhs_index = 0;
				std::size_t output_index = 0;

				for (std::size_t i = 0; i < count; ++i)
				{
					forward_impl(
						&lhs_->output()[0],
						&rhs_->output()[rhs_index],
						&this->output()[output_index]);

					rhs_index += rhs_size_;
					output_index += output_size_;
				}
			}
			else if (rhs_->output().size() == rhs_size_)
			{
				BOOST_ASSERT(lhs_->output().size() % lhs_size_ == 0);

				std::size_t count = lhs_->output().size() / lhs_size_;
				std::size_t total_output_size = output_size_ * count;

				if (this->output().size() != total_output_size)
					this->output().resize(total_output_size);

				std::size_t lhs_index = 0;
				std::size_t output_index = 0;

				for (std::size_t i = 0; i < count; ++i)
				{
					forward_impl(
						&lhs_->output()[lhs_index],
						&rhs_->output()[0],
						&this->output()[output_index]);

					lhs_index += lhs_size_;
					output_index += output_size_;
				}
			}
			else
			{
				BOOST_ASSERT(false);
			}
		}

		virtual void backward() override
		{
			if (lhs_->output().size() == lhs_size_ &&
				rhs_->output().size() == rhs_size_)
			{
				backward_impl(
					&lhs_->output_grad()[0],
					&rhs_->output_grad()[0],
					&lhs_->output()[0],
					&rhs_->output()[0],
					&this->output_grad()[0]);
			}
			else if (lhs_->output().size() == lhs_size_)
			{
				std::size_t count = rhs_->output().size() / rhs_size_;

				std::size_t rhs_index = 0;
				std::size_t output_index = 0;

				for (std::size_t i = 0; i < count; ++i)
				{
					backward_impl(
						&lhs_->output_grad()[0],
						&rhs_->output_grad()[rhs_index],
						&lhs_->output()[0],
						&rhs_->output()[rhs_index],
						&this->output_grad()[output_index]);

					rhs_index += rhs_size_;
					output_index += output_size_;
				}
			}
			else if (rhs_->output().size() == rhs_size_)
			{
				std::size_t count = lhs_->output().size() / lhs_size_;

				std::size_t lhs_index = 0;
				std::size_t output_index = 0;

				for (std::size_t i = 0; i < count; ++i)
				{
					backward_impl(
						&lhs_->output_grad()[lhs_index],
						&rhs_->output_grad()[0],
						&lhs_->output()[lhs_index],
						&rhs_->output()[0],
						&this->output_grad()[output_index]);

					lhs_index += lhs_size_;
					output_index += output_size_;
				}
			}
			else
			{
				BOOST_ASSERT(false);
			}
		}

		virtual void enumerate_children(const std::function<void(expression_node_base*)>& callback) override
		{
			callback(lhs_.get());
{'fraction_non_alphanumeric': 0.16444336648071792, 'fraction_numerical': 0.006791171477079796, 'mean_word_length': 3.1905487804878048, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 99, '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': '6601316', 'n_tokens_mistral': 3861, 'n_tokens_neox': 3018, 'n_words': 512}