89 lines
3.5 KiB
C++
89 lines
3.5 KiB
C++
#include <catch.hpp>
|
|
#include "../common.h"
|
|
|
|
#include <pfor/parallelizable.h>
|
|
#include <pfor/index/operators.h>
|
|
|
|
TEST_CASE("RWControl") {
|
|
constexpr pfor::expr::Access R = pfor::expr::Access::read, W = pfor::expr::Access::write;
|
|
|
|
pfor::Index it;
|
|
|
|
using OT1R = pfor::expr::OperandTag<class ID1, R, pfor::Index>;
|
|
using OT2R = pfor::expr::OperandTag<class ID2, R, pfor::Index>;
|
|
using OT3R = pfor::expr::OperandTag<class ID3, R, pfor::Index>;
|
|
using OT1W = pfor::expr::OperandTag<class ID1, W, pfor::Index>;
|
|
using OT2W = pfor::expr::OperandTag<class ID2, W, pfor::Index>;
|
|
using OT3W = pfor::expr::OperandTag<class ID3, W, pfor::Index>;
|
|
|
|
using Tags1R = pfor::Pack<OT1R>;
|
|
using Tags1R2R = pfor::Pack<OT1R, OT2R>;
|
|
using Tags1R2R3R = pfor::Pack<OT1R, OT2R, OT3R>;
|
|
using Tags1W2R = pfor::Pack<OT1W, OT2R>;
|
|
using Tags1W1R2R = pfor::Pack<OT1W, OT1R, OT2R>;
|
|
using Tags1W1R2R3R = pfor::Pack<OT1W, OT1R, OT2R, OT3R>;
|
|
using Tags1W2W3R3R = pfor::Pack<OT1W, OT2W, OT3R, OT3R>;
|
|
using Tags1R2W3W3R = pfor::Pack<OT1R, OT2W, OT3W, OT3R>;
|
|
using Tags1R2W3R3R = pfor::Pack<OT1R, OT2W, OT3R, OT3R>;
|
|
|
|
SECTION("RWControl") {
|
|
SECTION("Constant index") {
|
|
using C0 = decltype(pfor::ctv<0>);
|
|
|
|
using TagsW = pfor::Pack<pfor::expr::OperandTag<class ID0, W, C0>>;
|
|
using TagsR = pfor::Pack<pfor::expr::OperandTag<class ID0, R, C0>>;
|
|
using TagsRW = pfor::Pack<pfor::expr::OperandTag<class ID0, R, C0>, pfor::expr::OperandTag<class ID0, W, C0>>;
|
|
|
|
REQUIRE_FALSE(pfor::rwControl<TagsW>);
|
|
REQUIRE(pfor::rwControl<TagsR>);
|
|
REQUIRE_FALSE(pfor::rwControl<TagsRW>);
|
|
}
|
|
|
|
SECTION("Same index") {
|
|
REQUIRE(pfor::rwControl<Tags1R>);
|
|
REQUIRE(pfor::rwControl<Tags1R2R>);
|
|
REQUIRE(pfor::rwControl<Tags1R2R>);
|
|
REQUIRE(pfor::rwControl<Tags1R2R3R>);
|
|
REQUIRE(pfor::rwControl<Tags1W2R>);
|
|
REQUIRE(pfor::rwControl<Tags1W1R2R>);
|
|
REQUIRE(pfor::rwControl<Tags1W1R2R3R>);
|
|
REQUIRE(pfor::rwControl<Tags1W2W3R3R>);
|
|
REQUIRE(pfor::rwControl<Tags1R2W3W3R>);
|
|
REQUIRE(pfor::rwControl<Tags1R2W3R3R>);
|
|
}
|
|
|
|
SECTION("Different indices") {
|
|
using OT1RI = pfor::expr::OperandTag<class ID1, R, decltype(pfor::ctv<2>*it)>;
|
|
using OT2RI = pfor::expr::OperandTag<class ID2, R, decltype(pfor::ctv<2>*it)>;
|
|
using OT3RI = pfor::expr::OperandTag<class ID3, R, decltype(pfor::ctv<2>*it)>;
|
|
using OT1WI = pfor::expr::OperandTag<class ID1, W, decltype(pfor::ctv<2>*it+pfor::ctv<1>)>;
|
|
using OT2WI = pfor::expr::OperandTag<class ID2, W, decltype(pfor::ctv<2>*it+pfor::ctv<1>)>;
|
|
using OT3WI = pfor::expr::OperandTag<class ID3, W, decltype(pfor::ctv<2>*it+pfor::ctv<1>)>;
|
|
|
|
using Tags1 = pfor::Pack<OT1RI, OT1WI, OT2RI, OT2WI, OT3RI, OT3WI>;
|
|
using Tags2 = pfor::Pack<OT1RI, OT1W>;
|
|
using Tags3 = pfor::Pack<OT1WI, OT1W>;
|
|
using Tags4 = pfor::Pack<OT1RI, OT1R>;
|
|
|
|
REQUIRE(pfor::rwControl<Tags1>);
|
|
REQUIRE_FALSE(pfor::rwControl<Tags2>);
|
|
REQUIRE_FALSE(pfor::rwControl<Tags3>);
|
|
REQUIRE(pfor::rwControl<Tags4>);
|
|
}
|
|
|
|
SECTION("Linear Diophantine Cases") {
|
|
using LD0 = decltype(pfor::ctv<2>*it);
|
|
using LD1 = decltype(it+pfor::ctv<5>);
|
|
using LD2 = decltype(pfor::ctv<2>*it+pfor::ctv<5>);
|
|
|
|
using Tags0 = pfor::Pack<pfor::expr::OperandTag<class ID0, R, LD0>, pfor::expr::OperandTag<class ID0, W, LD1>>;
|
|
using Tags1 = pfor::Pack<pfor::expr::OperandTag<class ID0, R, LD0>, pfor::expr::OperandTag<class ID0, W, LD2>>;
|
|
using Tags2 = pfor::Pack<pfor::expr::OperandTag<class ID0, R, LD1>, pfor::expr::OperandTag<class ID0, W, LD2>>;
|
|
|
|
REQUIRE_FALSE(pfor::rwControl<Tags0>);
|
|
REQUIRE(pfor::rwControl<Tags1>);
|
|
REQUIRE_FALSE(pfor::rwControl<Tags2>);
|
|
}
|
|
}
|
|
}
|