ffi.cc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // -*- mode: c++; coding: utf-8 -*-
  2. // Fortran FFI sandbox, sanity checks
  3. // $CXX -o ffi ffi.cc -Wl,-rpath . -L . -lexample -std=c++20
  4. // (c) Daniel Llorens - 2021
  5. // This library is free software; you can redistribute it and/or modify it under
  6. // the terms of the GNU General Public License as published by the Free
  7. // Software Foundation; either version 3 of the License, or (at your option) any
  8. // later version.
  9. #include <ISO_Fortran_binding.h>
  10. #include <iostream>
  11. #include <type_traits>
  12. #include <cassert>
  13. using std::cout, std::endl;
  14. extern "C"
  15. {
  16. double lookup_xy(double const * x, double const * y, CFI_cdesc_t * cdesc);
  17. void fillerf32(CFI_cdesc_t *);
  18. }
  19. int
  20. main()
  21. {
  22. cout << "---- check constants" << endl;
  23. {
  24. cout << "CFI_type_float_Complex " << CFI_type_float_Complex << endl;
  25. cout << "CFI_type_double_Complex " << CFI_type_double_Complex << endl;
  26. }
  27. cout << "---- rank 2 args, scalar return" << endl;
  28. {
  29. constexpr int n0 = 3;
  30. constexpr int n1 = 4;
  31. double data[n0][n1] = {{ 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }};
  32. CFI_CDESC_T(CFI_MAX_RANK) cdesc;
  33. auto pcdesc = (CFI_cdesc_t *) &cdesc;
  34. pcdesc->base_addr = data;
  35. pcdesc->elem_len = sizeof(double);
  36. pcdesc->version = CFI_VERSION;
  37. pcdesc->rank = 2;
  38. pcdesc->attribute = CFI_attribute_pointer;
  39. pcdesc->type = CFI_type_double;
  40. pcdesc->dim[0] = { .lower_bound = 0, .extent = n0, .sm = n1*sizeof(double) };
  41. pcdesc->dim[1] = { .lower_bound = 0, .extent = n1, .sm = 1*sizeof(double) };
  42. double x(1);
  43. double y(2);
  44. cout << "in C: " << lookup_xy(&x, &y, pcdesc) << endl;
  45. }
  46. // after https://fortran-lang.discourse.group/t/iso-c-binding-pass-an-array-from-c-to-fortran-edit-python-interop-content/514/4
  47. cout << "---- inout array " << endl;
  48. {
  49. int N = 4;
  50. float data[N] = { 9, 8, 7, 6 };
  51. CFI_CDESC_T(1) cdesc;
  52. CFI_index_t ext[1] = { 4 };
  53. auto pcdesc = (CFI_cdesc_t *) &cdesc;
  54. assert(CFI_SUCCESS == CFI_establish(pcdesc, data, CFI_attribute_pointer, CFI_type_float, 0, 1, ext));
  55. cout << "in C, pre call " << (float *)data << endl;
  56. for (int i=0; i<N; ++i) {
  57. cout << data[i] << ", ";
  58. }
  59. cout << endl;
  60. fillerf32(pcdesc);
  61. cout << "in C, post call " << (float *)data << endl;
  62. for (int i=0; i<N; ++i) {
  63. cout << data[i] << ", ";
  64. }
  65. cout << endl;
  66. }
  67. cout << "---- inout array, filling the descriptor manually" << endl;
  68. {
  69. int N = 4;
  70. float data[N] = { 9, 8, 7, 6 };
  71. CFI_CDESC_T(CFI_MAX_RANK) cdesc;
  72. auto pcdesc = (CFI_cdesc_t *) &cdesc;
  73. pcdesc->base_addr = data;
  74. pcdesc->elem_len = sizeof(float);
  75. pcdesc->version = CFI_VERSION;
  76. pcdesc->rank = 1;
  77. pcdesc->attribute = CFI_attribute_pointer;
  78. pcdesc->type = CFI_type_double;
  79. pcdesc->dim[0] = { .lower_bound = 0, .extent = 4, .sm = sizeof(float) };
  80. cout << "in C, pre call " << (float *)data << endl;
  81. for (int i=0; i<N; ++i) {
  82. cout << data[i] << ", ";
  83. }
  84. cout << endl;
  85. fillerf32(pcdesc);
  86. cout << "in C, post call " << (float *)data << endl;
  87. for (int i=0; i<N; ++i) {
  88. cout << data[i] << ", ";
  89. }
  90. cout << endl;
  91. }
  92. return 0;
  93. }