2016-03-30 13 views
1

HDF5 Thread Safe kütüphanesinin kullanımıyla ilgili bir sorum var.
Şu anda "HDF5_ENABLE_PARALLEL" veya "HDF5_ENABLE_THREADSAFE" seçenekleri kullanılarak bir iş arkadaşım tarafından derlenen HDF5 C++ kitaplığı (statik) örneğiyle çalışıyorum.HDF5 Kullanıyor Güvenli Kitap Kütüphane

Yapmaya çalıştığım şey, birden çok iş parçacığı kullanarak bazı veriler içeren bir HDF dosyasına erişmektir. Verilerin gerçek okumasının paralel olması gerekmez.

Kodum şu anda nasılsa böyle basitleştirilmiş görünüyor:

// includes etc. 

int main() { 

    H5File t_file(FILENAME, H5F_ACC_RDONLY); 

    thread t1(read_row, cref(t_file), 0); 
    thread t2(read_row, cref(t_file), 1); 

    t1.join(); 
    t2.join(); 

    return 0; 

} 

void read_row(const H5File & p_file, size_t p_row){ 

    double data[DIM_Y][DIM_X]; 

    try { 

    DataSet t_dataset = p_file.openDataSet("/Group0/Set0"); 
    DataSpace t_dataspace = t_dataset.getSpace(); 

    hsize_t dims[2]; 
    auto status = t_dataspace.getSimpleExtentDims(dims, nullptr); 


    hsize_t count[2] = { 1, DIM_X }; 
    hsize_t offset[2] = { p_row, 0 }; 
    t_dataspace.selectHyperslab(H5S_SELECT_SET, count, offset); 

    hsize_t mem_dim[2] = { 1, DIM_X }; 
    DataSpace t_memspace(RANK, mem_dim); 
    hsize_t mem_offset[2] = { 0, 0 }; 
    t_memspace.selectHyperslab(H5S_SELECT_SET, count, mem_offset); 

    t_dataset.read(data, PredType::NATIVE_DOUBLE, t_memspace, t_dataspace); 

    } 
    catch (...){ 
    cout << "Caught some exception" << endl; 
    } 
} 

kod derler ve ben programı çalıştırırsanız zaman her şeyin en iyi gider.

HDF5-DIAG: Error detected in HDF5 (1.8.16) thread 0: 
    #000: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5D.c line 358 in H5Dopen2(): not found 
    major: Dataset 
    minor: Object not found 
    #001: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5Gloc.c line 430 in H5G_loc_find(): can't find object 
    major: Symbol table 
    minor: Object not found 
    #002: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5Gtraverse.c line 861 in H5G_traverse(): internal path traversal failed 
    major: Symbol table 
    minor: Object not found 
    #003: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5Gtraverse.c line 596 in H5G_traverse_real(): can't look up component 
    major: Symbol table 
    minor: Object not found 
    #004: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5Gobj.c line 1139 in H5G__obj_lookup(): can't check for link info message 
    major: Symbol table 
    minor: Can't get value 
    #005: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5Gobj.c line 333 in H5G__obj_get_linfo(): unable to read object header 
    major: Symbol table 
    minor: Can't get value 
    #006: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5Omessage.c line 896 in H5O_msg_exists(): unable to release object header 
    major: Object header 
    minor: Unable to unprotect metadata 
    #007: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5O.c line 1963 in H5O_unprotect(): unable to release object header 
    major: Object header 
    minor: Unable to unprotect metadata 
    #008: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5Gobj.c line 1524 in H5O_msg_exists(): H5G__obj_get_linfo 
    major: Object cache 
    minor: Unable to unprotect metadata 
    #009: D:\Projects\CANoe\90\CMake-hdf5-1.8.16\hdf5-1.8.16\src\H5C.c line 5281 in H5C_unprotect(): Entry already unprotected?? 
    major: Object cache 
    minor: Unable to unprotect metadata 

Ben kütüphane kendisi mevcut haliyle parçacığı güvenli olmadığı için bu oluşur şüpheli:
Bazen ancak aşağıdaki hata iletisi alıyorum.

Şimdi sorum var:
Kütüphane --enable-threadsafe seçeneğini kullanarak yeniden derlerse, yukarıdaki gibi bir HDF5 dosyası ile çalışabilir miyim.
Kitaplık kendisi, bir seferde yalnızca bir iş parçacığının bir dosyaya eriştiğinden (veya bir API çağrısı yapıyor olduğundan) emin olmalıdır?
Kitaplığı yeniden derlersek, yine de C++ API'sini kullanabilir miyim?

Ayrıca bir muteks kullanarak API çağrılarını kilitlemeye çalıştım ancak yine de bazı sorunlarım vardı.

Burada birileri bana sorunumun bir cevabını verebilirse çok minnettar olurum. Umarım kendimi yeterince iyi açıkladım. Üzgünüm, bu biraz uzun olsun;).

Şimdiden teşekkürler.

+0

Bu dosyayı değiştirmeniz gerekiyor mu? Değilse, dosyayı her bir iş parçacığı içinde açmayı deneyebilirsiniz, yani, H5File t_file (FILENAME, H5F_ACC_RDONLY); '' read_row() 'içine hareket ettirebilirsiniz. –

+0

Her neyse '--enable threadn 'yapılandırma seçeneğine güvenmek tehlikeli olabilir. Aslında ne anlama geliyor?HDF5 kütüphane kaynak kodunda bazı kilitleme mekanizmalarına olanak sağlayacaktır. Ancak bu kilitleme mekanizması, belirli bir diş açma parantezine dayanır. Bu, Pthreads kütüphanesidir, fakat C++ 11 iş parçacığı kullanıyorsunuzdur (muhtemelen Pthreads üzerinde de yerleşiktir). Farklı diş açma paradigmalarının karıştırılması çok kırılgandır ve genellikle tavsiye edilmez. Aynı nedenden dolayı, HDF5'in OpenMP ile birlikte kullanılması önerilmez. –

+0

@DanielLangr no Dosyayı değiştirmeyeceğim, dolayısıyla H5File Nesnesini iş parçacığına taşıyabilmek bir çözüm olabilir. Bunu yukarıdaki örnekte denedim ve şimdiye kadar işe yaradı. Ne yazık ki kazalar daha önceden tahmin edilemez bir şekilde gerçekleşti, bu yüzden emin olamadım. Ama kütüphaneyi bu şekilde kullanabileceğimi düşünüyorum. Threadafe olan ve gerçek IO'yu yapan tek bir sarıcı. Ve bu sarıcı, birden çok çalışan iş parçacığı tarafından kullanılabilir. Bence bu işe yarayabilir. Cevap için teşekkürler. – YoLieR

cevap

1

HDF5 documentation'a göre, --enable-threadsafe ile derlendiğinde birinci düzey iş parçacığı güvenliği sağlar. Ancak bu sadece C kütüphanesi için geçerlidir. Yüksek seviyeli C++ kütüphanesi iplik güvenliğini desteklemez. Eğer

./configure --enable-threadsafe --enable-cxx 

'u çalıştırmaya çalışırsanız bir hata mesajı alırsınız. Eğer C++ kullanmak istiyorsanız, "--enable-threadsafe" seçeneği olmadan hdf5'i derlemelisiniz ve aynı anda farklı thread'lardan hdf5 kütüphanesine erişmemelisiniz. Deneyimlerimden, HD + 5'e her zaman C++'daki aynı konudan erişmek daha iyidir.

Bazı Linux dağıtımları, C++ kitaplığını etkin bir şekilde keserek hem --enable-threadsafe hem de --enable-cxx izin vererek bu sınırlamayı "gideren" bir düzeltme eki uygular. Libhdf5'in daha yeni versiyonu, --enable-unsupported numaralı bir seçeneğe sahiptir ve bu, yama olmadan izin verir. Böyle bir "geliştirilmiş" hdf5 paketi kullanarak rasgele çökmeler elde edeceksiniz. Bu nedenle, "geliştirilmiş" kitaplığına sahip olup olmadığınızı kontrol edin ve gerekirse el ile yeniden derleyin.