Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

请教下如何将文件数据加载到全局数组中? #1

Open
caiwanli opened this issue Jul 19, 2023 · 3 comments
Open

请教下如何将文件数据加载到全局数组中? #1

caiwanli opened this issue Jul 19, 2023 · 3 comments

Comments

@caiwanli
Copy link

caiwanli commented Jul 19, 2023

void load_data(){
    using namespace Ring;
    run([]{
        struct record {
            int r_regionkey;
            char r_name[25];
        }CACHE_ALIGNED;
        const int64_t SZ=5;
        std::string filename = "/home/cwl/workspace/data/ring_data/region.txt";
        std::ifstream infile(filename);
        if (!infile) {
            std::cerr << "Failed to open file: " << filename << std::endl;
            return;
        }
        auto data = gmalloc<record>(SZ);
        auto data1 = data + 0;
        std::string line;
        int count = 0;
        while (std::getline(infile, line)) {
            // Process the line
            //record tmp_record;
            std::string tmp;
            std::istringstream iss(line);
            std::string token;
            std::getline(iss, token, '|');
            //data.ptr()->r_regionkey = std::stoi(token);
            sync_printf("++++++++++++++++++++++++++++++++++++++++++1");
            //std::vector<std::string> datas;
            //datas.push_back(token);
            call(data, [count](record *r){
              sync_printf(my_id(),"++++++++++++++++++++++++++++++++++++++++++2: ");
              r->r_regionkey = count;
            });
            std::getline(iss, token, '|');
            //std::strcpy(data.ptr()->r_name, token.c_str());
            call(data, [](record *r){
              sync_printf(my_id(),"++++++++++++++++++++++++++++++++++++++++++3");
              std::string token = "testring";
              std::strcpy(r->r_name, token.c_str());
            });
            data++;
            count++;
        }        
        pfor(data1, SZ, [](record *w){
          sync_printf(my_id(), "++++++++++++++++++++++++++++++++++++++++++4",w->r_regionkey, w->r_name);
        });
        infile.close();
        barrier();
        gfree(data);
        mlog_dump();
        //MLOG.dump();
    });//run
}

这是我的思路,但是我发现似乎call并不支持携带数据,这里匿名表达式直接捕获token的话,程序会报错,希望大佬能指点指点

@mengke-mk
Copy link
Collaborator

读文件到GlobalArray需要先读到Private的空间后再拷贝到GlobalArray中。可以参考 https://github.com/PAA-NCIC/RING/blob/master/src/graph/edgelist.cc#L46 这里读图数据的函数。这里确实可以封装一个read_file的函数放在“utils/IO.h”里来方便调用。

@caiwanli
Copy link
Author

caiwanli commented Jul 22, 2023

您好,孟博,这个load_csv我之前就已经看过,这样做的确可以将数据加载到GlobalArray中,但似乎这样有点多此一举。理论上GlobalArray被设计出来应该可以直接使用。这里我想确认下,我的代码思路是否正确,如果有call_with_data是否可以使用我上面的代码思路加载数据到内存?因为我发现,您好像实现过一版call_with_data,但是不知道啥原因您没有把它集成进来。还有一个关键问题,似乎GlobalAddress,这里T部分的大小不能超过64B。而我的一条记录已经超过这个大小限制。我看到这里的代码是有限制大小的

GlobalAddress<T> gmalloc(size_t size){
  ASSERT( BLOCK_SIZE%sizeof(T) == 0, "please pack the data_type size to divisor of 64 bytes!");
  return static_cast<GlobalAddress<T>>(rmalloc( sizeof(T)*size ));
}

这里把断言去掉会影响后续代码嘛?因为我的初步计划是基于RING去做一个查询引擎,类似grappa与Radish的关系(Radish会把SQL翻译成grappa并行代码)。如果GlobalAddress不支持大数据类型,即便把数据加载到私有内存也无法写入GlobalAddress。方便的话,孟博能留个联系方式嘛?最后,没想到孟博能回复我的消息,这里非常感谢孟博能再百忙中回复我,十分感激。

@mengke-mk
Copy link
Collaborator

mengke-mk commented Jul 24, 2023

@caiwanli

这个load_csv我之前就已经看过,这样做的确可以将数据加载到GlobalArray中,但似乎这样有点多此一举。

load_tsv这个主要是利用edgelist不关心顺序,希望数据载入后尽量避免数据跨节点的copy。因为GlobalArray数据是round-robin分布的,而读文件是分块顺序读入的,强行保序会导致不必要的通信。但这个实现确实不够具有一般性。

理论上GlobalArray被设计出来应该可以直接使用。这里我想确认下,我的代码思路是否正确。

GlobalArray设计上确实希望用户直观地像malloc出来的数组一样使用。在你提供的示例中,token应该是需要捕获的,不考虑性能的话,你的代码思路上我觉得没有问题的。call本身也支持携带数据(但是最好是POD或structure of POD,因为call里面会做序列化 (可以改进它让它更泛用一些)。像std::string没有触发SSO的话,序列化和传输的的可能只是个指针)。此外,数据在低于MAX_MESSAGE_SIZE时会使用内存池,高于此值时则会从heap上申请(频繁使用它性能会受影响)。

因为我发现,您好像实现过一版call_with_data,但是不知道啥原因您没有把它集成进来。

通过call捕获用户参数是更直观的使用方法,之后替换了这个call_with_data方法,这部分代码应该可以被移除。

还有一个关键问题,似乎GlobalAddress,这里T部分的大小不能超过64B。而我的一条记录已经超过这个大小限制。

GlobalArray的设计是把数据以BLOCK_SIZE为粒度,以round-robin的方式分散到集群中(BLOCK i分到 i%n的节点上)。这是为了处理负载均衡和false sharing的问题。T不能超过这个BLOCK_SIZE的原因是不希望数组的一个element分散到不同的节点上,这没有好处。现在BLOCK_SIZE被设为64是偏小的,可以把它改大一些。

方便的话,孟博能留个联系方式嘛

个人邮箱 septic.mkATgmail.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants