<commit_before>#ifndef DISPLACEMENT_OP_H_
#define DISPLACEMENT_OP_H_

#include <array>
#include <cmath>
#include "backend.h"
#include "cell.h"
#include "make_thread_safe.h"
#include "math_util.h"
#include "multiform_object.h"
#include "param.h"

namespace bdm {

using real_v = VcSoaBackend::real_v;
using real_t = VcSoaBackend::real_t;
using bool_v = VcSoaBackend::bool_v;

NEW_MEMBER_SELECTOR(DisplacementOpMemberSelector, CellExt<>, mass_location_,
                    CellExt<>, diameter_);

/// Defines the 3D physical interactions between physical objects (cylinders and
/// spheres).
class DisplacementOp {
 public:
  DisplacementOp() {}
  ~DisplacementOp() {}
  DisplacementOp(const DisplacementOp&) = delete;
  DisplacementOp& operator=(const DisplacementOp&) = delete;

  template <typename TContainer>
  void Compute(TContainer* cells) const {
#pragma omp parallel
    {
      auto thread_safe_cells = make_thread_safe(cells);
      const size_t n_vectors = thread_safe_cells->Vectors();
      std::array<aosoa<Cell<VcVectorBackend, DisplacementOpMemberSelector>,
                       VcVectorBackend>,
                 VcVectorBackend::kVecLen>
          neighbors;
#pragma omp for
      for (size_t i = 0; i < n_vectors; i++) {
        auto& cell = (*thread_safe_cells)[i];
        // Basically, the idea is to make the sum of all the forces acting
        // on the Point mass. It is stored in translationForceOnPointMass.
        // There is also a computation of the torque (only applied
        // by the daughter neurites), stored in rotationForce.

        // If we detect enough forces to make us  move, we will re-schedule us
        // cell.setOnTheSchedulerListForPhysicalObjects(false);

        // const auto& tf = cell.GetTractorForce();
        const std::array<real_v, 3>& tf = cell.GetTractorForce();
        // const std::array<real_v, 3> tf{0, 0, 0};

        // the 3 types of movement that can occurq
        // bool_v biological_translation(false);
        bool_v physical_translation(false);
        //      bool_v physical_rotation(false);

        real_v h(Param::kSimulationTimeStep);
        std::array<real_v, 3> movement_at_next_step{0, 0, 0};

        // BIOLOGY :
        // 0) Start with tractor force : What the biology defined as active
        // movement------------
        movement_at_next_step[0] += h * tf[0];
        movement_at_next_step[1] += h * tf[1];
        movement_at_next_step[2] += h * tf[2];

        // PHYSICS
        // the physics force to move the point mass
        std::array<real_v, 3> translation_force_on_point_mass{0, 0, 0};
        // 1) "artificial force" to maintain the sphere in the ecm simulation
        //    boundaries
        // todo add again
        // 2) Spring force from my neurites (translation and
        // rotation)-----------
        // todo add again
        // 3) Object avoidance force
        // --------------------------------------------
        //  (We check for every neighbor object if they touch us, i.e. push us
        //  away)
        cell.GetNeighbors(*cells, &neighbors);

        // todo remove VcVectorBackend with impl.
        for (size_t j = 0; j < VcVectorBackend::kVecLen; j++) {
          for (size_t k = 0; k < neighbors.at(j).Vectors(); k++) {
            auto& neighbor = neighbors.at(j)[k];
            std::array<real_v, 3> neighbor_force;
<commit_msg>Add software prefetching of neighbors in DisplacementOp<commit_after>#ifndef DISPLACEMENT_OP_H_
#define DISPLACEMENT_OP_H_

#include <array>
#include <cmath>
#include "backend.h"
#include "cell.h"
#include "make_thread_safe.h"
#include "math_util.h"
#include "multiform_object.h"
#include "param.h"

namespace bdm {

using real_v = VcSoaBackend::real_v;
using real_t = VcSoaBackend::real_t;
using bool_v = VcSoaBackend::bool_v;

NEW_MEMBER_SELECTOR(DisplacementOpMemberSelector, CellExt<>, mass_location_,
                    CellExt<>, diameter_);

/// Defines the 3D physical interactions between physical objects (cylinders and
/// spheres).
class DisplacementOp {
 public:
  DisplacementOp() {}
  ~DisplacementOp() {}
  DisplacementOp(const DisplacementOp&) = delete;
  DisplacementOp& operator=(const DisplacementOp&) = delete;

  template <typename TContainer>
  void Compute(TContainer* cells) const {
#pragma omp parallel
    {
      auto thread_safe_cells = make_thread_safe(cells);
      const size_t n_vectors = thread_safe_cells->Vectors();

      // define data structure for neigbors for neighbor_batch_size iterations
      const size_t neighbor_batch_size = 2;
      std::array<
          std::array<aosoa<Cell<VcVectorBackend, DisplacementOpMemberSelector>,
                           VcVectorBackend>,
                     VcVectorBackend::kVecLen>,
          neighbor_batch_size>
          neighbor_array;
#pragma omp for
      for (size_t i = 0; i < n_vectors; i++) {
        auto& cell = (*thread_safe_cells)[i];

        // prefetch neighbors
        if (i % neighbor_batch_size == 0) {
          for (size_t j = 0; j < neighbor_batch_size; j++) {
            size_t idx = j + i;
            if (idx < n_vectors) {
              (*thread_safe_cells)[idx].GetNeighbors(*cells,
                                                     &(neighbor_array[j]));
            }
          }
        }
        // get neighbors for current loop iteration
        const auto& neighbors = neighbor_array[i % neighbor_batch_size];

        // Basically, the idea is to make the sum of all the forces acting
        // on the Point mass. It is stored in translationForceOnPointMass.
        // There is also a computation of the torque (only applied
        // by the daughter neurites), stored in rotationForce.

        // If we detect enough forces to make us  move, we will re-schedule us
        // cell.setOnTheSchedulerListForPhysicalObjects(false);

        // const auto& tf = cell.GetTractorForce();
        const std::array<real_v, 3>& tf = cell.GetTractorForce();
        // const std::array<real_v, 3> tf{0, 0, 0};

        // the 3 types of movement that can occurq
        // bool_v biological_translation(false);
        bool_v physical_translation(false);
        //      bool_v physical_rotation(false);

        real_v h(Param::kSimulationTimeStep);
        std::array<real_v, 3> movement_at_next_step{0, 0, 0};

        // BIOLOGY :
        // 0) Start with tractor force : What the biology defined as active
        // movement------------
        movement_at_next_step[0] += h * tf[0];
        movement_at_next_step[1] += h * tf[1];
        movement_at_next_step[2] += h * tf[2];

        // PHYSICS
        // the physics force to move the point mass
        std::array<real_v, 3> translation_force_on_point_mass{0, 0, 0};
        // 1) "artificial force" to maintain the sphere in the ecm simulation
        //    boundaries
        // todo add again
        // 2) Spring force from my neurites (translation and
        // rotation)-----------
        // todo add again
        // 3) Object avoidance force
        // --------------------------------------------
        //  (We check for every neighbor object if they touch us, i.e. push us
        //  away)

        // todo remove VcVectorBackend with impl.
        for (size_t j = 0; j < VcVectorBackend::kVecLen; j++) {
          for (size_t k = 0; k < neighbors.at(j).Vectors(); k++) {
            auto& neighbor = neighbors.at(j)[k];
            std::array<real_v, 3> neighbor_force;

{'fraction_non_alphanumeric': 0.12070354457572503, 'fraction_numerical': 0.008190118152524168, 'mean_word_length': 2.34185733512786, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6680098', 'n_tokens_mistral': 2285, 'n_tokens_neox': 2205, 'n_words': 633}